Skip to content

Commit adebcd0

Browse files
feat: add sort by name, size, last modified and defaults to order of discovery
1 parent 477c337 commit adebcd0

6 files changed

Lines changed: 244 additions & 33 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,20 @@ cnkill /path/to/projects --node # find node_modules/ only
4141

4242
cnkill /path/to/projects --all # find both vendor/ and node_modules/
4343

44+
cnkill /path/to/projects --sort=size # sort by size
45+
4446
cnkill /path/to/projects --maxdepth=4 # limit search depth
47+
48+
cnkill cache --sort=modified # sort caches by last modified
4549
```
4650

4751
## Controls
4852

4953
| Key | Action |
5054
|-----|--------|
5155
| `` / `` | Navigate the list |
56+
| `` / `` | Page through the list |
57+
| `s` | Cycle sort mode |
5258
| `Space` | Delete the highlighted directory |
5359
| `q` / `Ctrl-C` | Quit |
5460

app/Commands/CacheKill.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class CacheKill extends Command
1616
*
1717
* @var string
1818
*/
19-
protected $signature = 'cache';
19+
protected $signature = 'cache
20+
{--sort=default : Sort by default, name, size, or modified}';
2021

2122
/**
2223
* The console command description.
@@ -35,7 +36,7 @@ class CacheKill extends Command
3536
* 'deleting' — rm -rf in progress
3637
* 'deleted' — rm -rf completed
3738
*
38-
* @var array<string, array{label: string, type: string, size: int|null, status: string}>
39+
* @var array<string, array{label: string, type: string, size: int|null, status: string, lastModified: int|null, order: int}>
3940
*/
4041
protected array $state = [];
4142

@@ -76,6 +77,10 @@ class CacheKill extends Command
7677

7778
public function handle(): int
7879
{
80+
if (! $this->initializeSortMode()) {
81+
return 1;
82+
}
83+
7984
$paths = $this->resolveCachePaths();
8085

8186
if (empty($paths)) {
@@ -88,13 +93,17 @@ public function handle(): int
8893
}
8994

9095
// Populate state and enqueue size calculations before entering the TUI
96+
$order = 0;
97+
9198
foreach ($paths as $dir => $entry) {
9299
$this->dirs[] = $dir;
93100
$this->state[$dir] = [
94101
'label' => $entry['label'],
95102
'type' => $entry['type'],
96103
'size' => null,
97104
'status' => 'calculating',
105+
'lastModified' => filemtime($dir) ?: null,
106+
'order' => $order++,
98107
];
99108
$this->enqueueSizeProcess($dir);
100109
}
@@ -188,24 +197,16 @@ protected function cleanupProcesses(): void
188197

189198
protected function writeListLines(): void
190199
{
191-
$count = count($this->dirs);
200+
$visibleDirs = $this->syncCursorState($this->visibleDirs());
201+
$count = count($visibleDirs);
192202
[$totalSize, $allSized, $deletedCount, $freedSize] = $this->computeStats();
193203

194-
// Clamp cursor / offset to current list length
195-
if ($count > 0 && $this->cursor >= $count) {
196-
$this->cursor = $count - 1;
197-
}
198-
199-
if ($this->scrollOffset > max(0, $count - $this->visibleRows)) {
200-
$this->scrollOffset = max(0, $count - $this->visibleRows);
201-
}
202-
203204
$visibleEnd = min($this->scrollOffset + $this->visibleRows, $count);
204205

205206
$numWidth = mb_strlen((string) $count);
206207

207208
for ($i = $this->scrollOffset; $i < $visibleEnd; $i++) {
208-
$dir = $this->dirs[$i];
209+
$dir = $visibleDirs[$i];
209210
$info = $this->state[$dir];
210211
$isActive = ($i === $this->cursor);
211212

app/Commands/CnKill.php

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ class CnKill extends Command
1717
* @var string
1818
*/
1919
protected $signature = 'process {path? : The path to search for vendor directories}
20-
{--maxdepth= : The maximum depth to search for vendor directories}
21-
{--node : Search for node_modules directories instead of vendor}
22-
{--all : Search for both vendor and node_modules directories}';
20+
{--maxdepth= : The maximum depth to search for vendor directories}
21+
{--node : Search for node_modules directories instead of vendor}
22+
{--all : Search for both vendor and node_modules directories}
23+
{--sort=default : Sort by default, name, size, or modified}';
2324

2425
/**
2526
* The console command description.
@@ -38,7 +39,7 @@ class CnKill extends Command
3839
* 'deleting' — rm -rf in progress
3940
* 'deleted' — rm -rf completed
4041
*
41-
* @var array<string, array{project: string, size: int|null, status: string, type: string, lastModified: int|null}>
42+
* @var array<string, array{project: string, size: int|null, status: string, type: string, lastModified: int|null, order: int}>
4243
*/
4344
protected array $state = [];
4445

@@ -129,6 +130,10 @@ public function handle(): int
129130
return 1;
130131
}
131132

133+
if (! $this->initializeSortMode()) {
134+
return 1;
135+
}
136+
132137
// Resolve package-manager cache dirs to exclude from scanning
133138
$this->excludePaths = $this->resolveExcludePaths();
134139

@@ -386,13 +391,15 @@ protected function registerDir(string $dir): void
386391
return;
387392
}
388393

394+
$order = count($this->dirs);
389395
$this->dirs[] = $dir;
390396
$this->state[$dir] = [
391397
'project' => basename($parent),
392398
'size' => null,
393399
'status' => 'calculating',
394400
'type' => $type,
395401
'lastModified' => $this->resolveLastModified($parent, $dir, $type),
402+
'order' => $order,
396403
];
397404

398405
$this->enqueueSizeProcess($dir);
@@ -458,18 +465,10 @@ protected function resolveLastModified(string $projectPath, string $dir, string
458465

459466
protected function writeListLines(): void
460467
{
461-
$count = count($this->dirs);
468+
$visibleDirs = $this->syncCursorState($this->visibleDirs());
469+
$count = count($visibleDirs);
462470
[$totalSize, $allSized, $deletedCount, $freedSize] = $this->computeStats();
463471

464-
// Clamp cursor / offset to current list length
465-
if ($count > 0 && $this->cursor >= $count) {
466-
$this->cursor = $count - 1;
467-
}
468-
469-
if ($this->scrollOffset > max(0, $count - $this->visibleRows)) {
470-
$this->scrollOffset = max(0, $count - $this->visibleRows);
471-
}
472-
473472
$visibleEnd = min($this->scrollOffset + $this->visibleRows, $count);
474473

475474
// Empty state while searching — hidden once done (status bar shows "done")
@@ -482,7 +481,7 @@ protected function writeListLines(): void
482481
$numWidth = mb_strlen((string) $count);
483482

484483
for ($i = $this->scrollOffset; $i < $visibleEnd; $i++) {
485-
$dir = $this->dirs[$i];
484+
$dir = $visibleDirs[$i];
486485
$info = $this->state[$dir];
487486
$isActive = ($i === $this->cursor);
488487

0 commit comments

Comments
 (0)