Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sort-] allow z[ and z] to reverse col sort dir or ignore col #2688

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions visidata/sort.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
from visidata import vd, asyncthread, Progress, Sheet, options, UNLOADED

@Sheet.api
def orderBy(sheet, *cols, reverse=False):
'Add *cols* to internal ordering and re-sort the rows accordingly. Pass *reverse* as True to order these *cols* descending. Pass empty *cols* (or cols[0] of None) to clear internal ordering.'
def orderBy(sheet, *cols, reverse=False, change_column=False):
'''Add *cols* to internal ordering and re-sort the rows accordingly.
Pass *reverse* as True to order these *cols* descending.
Pass empty *cols* (or cols[0] of None) to clear internal ordering.
Set *change_column* to True to change the sort status of a single column: add/remove/invert it.
*cols* must have length 1. Sort columns that had higher priority are unchanged. Lower-priority columns are removed.
If *change_column* is False, *cols* will add to the existing ordering columns.'''

if options.undo:
vd.addUndo(setattr, sheet, '_ordering', copy(sheet._ordering))
if sheet._ordering:
Expand All @@ -17,9 +23,16 @@ def orderBy(sheet, *cols, reverse=False):
cols = cols[1:]
do_sort = True

for c in cols:
sheet._ordering.append((c, reverse))
if change_column:
if len(cols) > 1:
vd.fail('sort order edit must only be applied to a single column')
new_ordering = edit_ordering(sheet._ordering, cols[0], reverse)
sheet._ordering = new_ordering
do_sort = True
else:
for c in cols:
sheet._ordering.append((c, reverse))
do_sort = True

if do_sort:
sheet.sort()
Expand All @@ -35,6 +48,26 @@ def __lt__(self, other):
return other.obj < self.obj


def edit_ordering(ordering, col, reverse):
'''Return a modified ordering based on editing a single column *col*: add it, remove it, or flip its direction.
Columns after *col* in the ordering (with lower sort priority) are also removed from the ordering.
*ordering* is a list of tuples: (Column, boolean), where the boolean defines the sort direction.
'''
new_ordering = []
# handle changes to status of columns that are already in the ordering: add/remove/flip
changed = False
for c, old_reverse in ordering:
if c == col:
if reverse != old_reverse: # reverse the column's sort direction
new_ordering.append((c, reverse))
# if the sort direction is unchanged, remove the column from the ordering
changed = True
# columns after the edited column will be dropped from the ordering
break
new_ordering.append((c, old_reverse))
if not changed:
new_ordering.append((col, reverse))
return new_ordering

@Sheet.cached_property
def ordering(sheet) -> 'list[tuple[Column, bool]]':
Expand Down Expand Up @@ -84,8 +117,10 @@ def _sortkey(r):
Sheet.addCommand('g]', 'sort-keys-desc', 'orderBy(None, *keyCols, reverse=True)', 'sort descending by all key columns; replace any existing sort criteria')

# add to existing sort criteria
Sheet.addCommand('z[', 'sort-asc-add', 'orderBy(cursorCol)', 'sort ascending by current column; add to existing sort criteria')
Sheet.addCommand('z]', 'sort-desc-add', 'orderBy(cursorCol, reverse=True)', 'sort descending by current column; add to existing sort criteria')
Sheet.addCommand('', 'sort-asc-add', 'orderBy(cursorCol)', 'sort ascending by current column; add to existing sort criteria')
Sheet.addCommand('', 'sort-desc-add', 'orderBy(cursorCol, reverse=True)', 'sort descending by current column; add to existing sort criteria')
Sheet.addCommand('z[', 'sort-asc-change', 'orderBy(cursorCol, change_column=True)', 'sort ascending by current column; keep higher priority sort criteria')
Sheet.addCommand('z]', 'sort-desc-change', 'orderBy(cursorCol, reverse=True, change_column=True)', 'sort descending by current column; keep higher priority sort criteria')
Sheet.addCommand('gz[', 'sort-keys-asc-add', 'orderBy(*keyCols)', 'sort ascending by all key columns; add to existing sort criteria')
Sheet.addCommand('gz]', 'sort-keys-desc-add', 'orderBy(*keyCols, reverse=True)', 'sort descending by all key columns; add to existing sort criteria')

Expand Down
Loading