diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-13 19:32:59 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-13 19:32:59 +0300 |
| commit | 270c226d8443c779374ee46631c4f385126b9a81 (patch) | |
| tree | 9a1d613d5ea5d6227103cbf71283e9149420a22d | |
| parent | d585f83e1c3757e1a1edf2802abfa6171b5234f3 (diff) | |
extract generic sortedWithState helper to deduplicate tab sort logic
Four near-identical sorted-rows functions (sortedFileSnapshots,
sortedDirSnapshots, sortedSyscallSnapshots, sortedProcessTableRows)
each repeated the same guard-clone-sort-tiebreak-apply pattern.
Replace them with a single generic sortedWithState[T,K] in sort.go
that accepts per-tab byKey and tiebreak comparators as parameters.
Remove now-unused slices imports from syscalls.go and processes.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | internal/tui/dashboard/files.go | 34 | ||||
| -rw-r--r-- | internal/tui/dashboard/processes.go | 18 | ||||
| -rw-r--r-- | internal/tui/dashboard/sort.go | 34 | ||||
| -rw-r--r-- | internal/tui/dashboard/syscalls.go | 18 |
4 files changed, 38 insertions, 66 deletions
diff --git a/internal/tui/dashboard/files.go b/internal/tui/dashboard/files.go index 3b85a73..d74ea29 100644 --- a/internal/tui/dashboard/files.go +++ b/internal/tui/dashboard/files.go @@ -177,41 +177,11 @@ func fileDirColumns(width int) []common.TableColumn { } func sortedFileSnapshots(rows []statsengine.FileSnapshot, sortState tableSortState[fileSortKey]) []statsengine.FileSnapshot { - if len(rows) == 0 { - return nil - } - if !sortState.active { - return rows - } - - sorted := slices.Clone(rows) - slices.SortFunc(sorted, func(left, right statsengine.FileSnapshot) int { - cmp := compareFileBySort(left, right, sortState.key) - if cmp == 0 { - cmp = compareFileDefault(left, right) - } - return sortState.apply(cmp) - }) - return sorted + return sortedWithState(rows, sortState, compareFileBySort, compareFileDefault) } func sortedDirSnapshots(rows []DirSnapshot, sortState tableSortState[fileDirSortKey]) []DirSnapshot { - if len(rows) == 0 { - return nil - } - if !sortState.active { - return rows - } - - sorted := slices.Clone(rows) - slices.SortFunc(sorted, func(left, right DirSnapshot) int { - cmp := compareDirBySort(left, right, sortState.key) - if cmp == 0 { - cmp = compareDirDefault(left, right) - } - return sortState.apply(cmp) - }) - return sorted + return sortedWithState(rows, sortState, compareDirBySort, compareDirDefault) } func compareFileBySort(left, right statsengine.FileSnapshot, key fileSortKey) int { diff --git a/internal/tui/dashboard/processes.go b/internal/tui/dashboard/processes.go index f4eedec..5481843 100644 --- a/internal/tui/dashboard/processes.go +++ b/internal/tui/dashboard/processes.go @@ -2,7 +2,6 @@ package dashboard import ( "fmt" - "slices" "strconv" "strings" @@ -63,22 +62,7 @@ func processColumns() []common.TableColumn { } func sortedProcessTableRows(rows []statsengine.ProcessSnapshot, sortState tableSortState[processSortKey]) []statsengine.ProcessSnapshot { - if len(rows) == 0 { - return nil - } - if !sortState.active { - return rows - } - - sorted := slices.Clone(rows) - slices.SortFunc(sorted, func(left, right statsengine.ProcessSnapshot) int { - cmp := compareProcessBySort(left, right, sortState.key) - if cmp == 0 { - cmp = compareProcessDefault(left, right) - } - return sortState.apply(cmp) - }) - return sorted + return sortedWithState(rows, sortState, compareProcessBySort, compareProcessDefault) } func compareProcessBySort(left, right statsengine.ProcessSnapshot, key processSortKey) int { diff --git a/internal/tui/dashboard/sort.go b/internal/tui/dashboard/sort.go index 399d0c5..718746a 100644 --- a/internal/tui/dashboard/sort.go +++ b/internal/tui/dashboard/sort.go @@ -1,5 +1,7 @@ package dashboard +import "slices" + type tableSortState[K comparable] struct { active bool key K @@ -74,3 +76,35 @@ func compareStringAsc(left, right string) int { return 0 } } + +// sortedWithState is the shared sort helper for all sortable dashboard tables. +// It avoids four near-identical functions (files, dirs, syscalls, processes) +// that each guard on empty/inactive, clone the slice, sort with a key +// comparator, fall back to a tiebreaker, and apply the reverse flag. +// +// - rows – the input slice (not modified; nil is returned when empty) +// - sortState – carries the active flag, selected key, and reverse flag +// - byKey – per-key comparator for the active sort column +// - tiebreak – stable fallback comparator used when byKey returns 0 +func sortedWithState[T any, K comparable]( + rows []T, + sortState tableSortState[K], + byKey func(left, right T, key K) int, + tiebreak func(left, right T) int, +) []T { + if len(rows) == 0 { + return nil + } + if !sortState.active { + return rows + } + sorted := slices.Clone(rows) + slices.SortFunc(sorted, func(left, right T) int { + cmp := byKey(left, right, sortState.key) + if cmp == 0 { + cmp = tiebreak(left, right) + } + return sortState.apply(cmp) + }) + return sorted +} diff --git a/internal/tui/dashboard/syscalls.go b/internal/tui/dashboard/syscalls.go index 3b64b12..90f40ca 100644 --- a/internal/tui/dashboard/syscalls.go +++ b/internal/tui/dashboard/syscalls.go @@ -2,7 +2,6 @@ package dashboard import ( "fmt" - "slices" "strconv" "time" @@ -96,22 +95,7 @@ func syscallColumns(width int) []common.TableColumn { } func sortedSyscallSnapshots(rows []statsengine.SyscallSnapshot, sortState tableSortState[syscallSortKey]) []statsengine.SyscallSnapshot { - if len(rows) == 0 { - return nil - } - if !sortState.active { - return rows - } - - sorted := slices.Clone(rows) - slices.SortFunc(sorted, func(left, right statsengine.SyscallSnapshot) int { - cmp := compareSyscallBySort(left, right, sortState.key) - if cmp == 0 { - cmp = compareSyscallDefault(left, right) - } - return sortState.apply(cmp) - }) - return sorted + return sortedWithState(rows, sortState, compareSyscallBySort, compareSyscallDefault) } func compareSyscallBySort(left, right statsengine.SyscallSnapshot, key syscallSortKey) int { |
