summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Milde <daniel@milde.cz>2024-04-21 01:09:34 +0200
committerDaniel Milde <daniel@milde.cz>2024-04-21 01:16:12 +0200
commita3ad561932dab74114e6ed41cb9475dc57b74082 (patch)
tree2014e37669e58af8c78660a3fae51d4a34d0002c
parentb8836d336b371e00c44ed61bec34fb3914abc709 (diff)
feat: ignore item
-rw-r--r--tui/format.go14
-rw-r--r--tui/format_test.go35
-rw-r--r--tui/keys.go23
-rw-r--r--tui/keys_test.go81
-rw-r--r--tui/show.go36
-rw-r--r--tui/tui.go3
-rw-r--r--tui/tui_test.go4
7 files changed, 173 insertions, 23 deletions
diff --git a/tui/format.go b/tui/format.go
index c0913e5..84ad967 100644
--- a/tui/format.go
+++ b/tui/format.go
@@ -9,10 +9,12 @@ import (
"github.com/rivo/tview"
)
-func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked bool) string {
+func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked, ignored bool) string {
var part int
- if ui.ShowApparentSize {
+ if ignored {
+ part = 0
+ } else if ui.ShowApparentSize {
part = int(float64(item.GetSize()) / float64(maxSize) * 100.0)
} else {
part = int(float64(item.GetUsage()) / float64(maxUsage) * 100.0)
@@ -20,7 +22,7 @@ func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked
row := string(item.GetFlag())
- if ui.UseColors && !marked {
+ if ui.UseColors && !marked && !ignored {
row += "[#e67100::b]"
} else {
row += "[::b]"
@@ -39,7 +41,7 @@ func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked
}
if ui.showItemCount {
- if ui.UseColors && !marked {
+ if ui.UseColors && !marked && !ignored {
row += "[#e67100::b]"
} else {
row += "[::b]"
@@ -48,7 +50,7 @@ func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked
}
if ui.showMtime {
- if ui.UseColors && !marked {
+ if ui.UseColors && !marked && !ignored {
row += "[#e67100::b]"
} else {
row += "[::b]"
@@ -69,7 +71,7 @@ func (ui *UI) formatFileRow(item fs.Item, maxUsage int64, maxSize int64, marked
}
if item.IsDir() {
- if ui.UseColors && !marked {
+ if ui.UseColors && !marked && !ignored {
row += "[#3498db::b]/"
} else {
row += "[::b]/"
diff --git a/tui/format_test.go b/tui/format_test.go
index 97f8d1d..7ffab6c 100644
--- a/tui/format_test.go
+++ b/tui/format_test.go
@@ -75,7 +75,7 @@ func TestEscapeName(t *testing.T) {
Usage: 10,
}
- assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false), "Aaa [red[] bbb")
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false, false), "Aaa [red[] bbb")
}
func TestMarked(t *testing.T) {
@@ -99,8 +99,33 @@ func TestMarked(t *testing.T) {
Usage: 10,
}
- assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), true), "✓ Aaa")
- assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false), "[##########] Aaa")
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), true, false), "✓ Aaa")
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false, false), "[##########] Aaa")
+}
+
+func TestIgnored(t *testing.T) {
+ simScreen := testapp.CreateSimScreen()
+ defer simScreen.Fini()
+
+ app := testapp.CreateMockedApp(true)
+ ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, false, false, false, false)
+ ui.ignoredRows[0] = struct{}{}
+ ui.useOldSizeBar = true
+
+ dir := &analyze.Dir{
+ File: &analyze.File{
+ Usage: 10,
+ },
+ }
+
+ file := &analyze.File{
+ Name: "Aaa",
+ Parent: dir,
+ Usage: 10,
+ }
+
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false, true), "[ ] Aaa")
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false, false), "[##########] Aaa")
}
func TestSizeBar(t *testing.T) {
@@ -122,7 +147,7 @@ func TestSizeBar(t *testing.T) {
Usage: 10,
}
- assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false), "██████████▏Aaa")
+ assert.Contains(t, ui.formatFileRow(file, file.GetUsage(), file.GetSize(), false, false), "██████████▏Aaa")
}
func TestOldSizeBar(t *testing.T) {
@@ -146,5 +171,5 @@ func TestOldSizeBar(t *testing.T) {
Usage: 10,
}
- assert.Contains(t, ui.formatFileRow(file, dir.GetUsage(), dir.GetSize(), false), "[##### ] Aaa")
+ assert.Contains(t, ui.formatFileRow(file, dir.GetUsage(), dir.GetSize(), false, false), "[##### ] Aaa")
}
diff --git a/tui/keys.go b/tui/keys.go
index 25dd557..c28ceb5 100644
--- a/tui/keys.go
+++ b/tui/keys.go
@@ -260,6 +260,8 @@ func (ui *UI) handleMainActions(key *tcell.EventKey) *tcell.EventKey {
return nil
case ' ':
ui.handleMark()
+ case 'I':
+ ui.ignoreItem()
}
return key
}
@@ -324,3 +326,24 @@ func (ui *UI) handleMark() {
ui.fileItemMarked(row)
}
+
+func (ui *UI) ignoreItem() {
+ if ui.currentDir == nil {
+ return
+ }
+ // do not allow ignoring parent dir
+ row, column := ui.table.GetSelection()
+ selectedFile, ok := ui.table.GetCell(row, column).GetReference().(fs.Item)
+ if !ok || selectedFile == ui.currentDir.GetParent() {
+ return
+ }
+
+ if _, ok := ui.ignoredRows[row]; ok {
+ delete(ui.ignoredRows, row)
+ } else {
+ ui.ignoredRows[row] = struct{}{}
+ }
+ ui.showDir()
+ // select next row if possible
+ ui.table.Select(min(row+1, ui.table.GetRowCount()-1), 0)
+}
diff --git a/tui/keys_test.go b/tui/keys_test.go
index 6688999..cb7baa8 100644
--- a/tui/keys_test.go
+++ b/tui/keys_test.go
@@ -364,6 +364,18 @@ func TestMarkEmpty(t *testing.T) {
assert.NotNil(t, key)
}
+func TestIgnoreEmpty(t *testing.T) {
+ simScreen := testapp.CreateSimScreen()
+ defer simScreen.Fini()
+
+ app := testapp.CreateMockedApp(true)
+ ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false)
+ ui.done = make(chan struct{})
+
+ key := ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, 'I', 0))
+ assert.NotNil(t, key)
+}
+
func TestDelete(t *testing.T) {
fin := testdir.CreateTestDir()
defer fin()
@@ -528,6 +540,36 @@ func TestMarkParent(t *testing.T) {
assert.Equal(t, len(ui.markedRows), 0)
}
+func TestIgnoreParent(t *testing.T) {
+ fin := testdir.CreateTestDir()
+ defer fin()
+ simScreen := testapp.CreateSimScreen()
+ defer simScreen.Fini()
+
+ app := testapp.CreateMockedApp(true)
+ ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false)
+ ui.done = make(chan struct{})
+ ui.askBeforeDelete = false
+ err := ui.AnalyzePath("test_dir", nil)
+ assert.Nil(t, err)
+
+ <-ui.done // wait for analyzer
+
+ for _, f := range ui.app.(*testapp.MockedApp).GetUpdateDraws() {
+ f()
+ }
+
+ assert.Equal(t, "test_dir", ui.currentDir.GetName())
+ assert.Equal(t, 1, ui.table.GetRowCount())
+
+ ui.table.Select(0, 0)
+
+ ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0))
+ ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, 'I', 0))
+
+ assert.Equal(t, len(ui.ignoredRows), 0)
+}
+
func TestEmptyDir(t *testing.T) {
fin := testdir.CreateTestDir()
defer fin()
@@ -604,6 +646,45 @@ func TestMarkedEmptyDir(t *testing.T) {
assert.NoDirExists(t, "test_dir/nested/subnested")
}
+func TestIgnoreDir(t *testing.T) {
+ fin := testdir.CreateTestDir()
+ defer fin()
+ simScreen := testapp.CreateSimScreen()
+ defer simScreen.Fini()
+
+ app := testapp.CreateMockedApp(true)
+ ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false)
+ ui.done = make(chan struct{})
+ ui.askBeforeDelete = false
+ err := ui.AnalyzePath("test_dir", nil)
+ assert.Nil(t, err)
+
+ <-ui.done // wait for analyzer
+
+ for _, f := range ui.app.(*testapp.MockedApp).GetUpdateDraws() {
+ f()
+ }
+
+ assert.Equal(t, "test_dir", ui.currentDir.GetName())
+
+ assert.Equal(t, 1, ui.table.GetRowCount())
+
+ ui.table.Select(0, 0)
+
+ ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0)) // into nested
+ assert.Equal(t, 3, ui.table.GetRowCount())
+
+ ui.table.Select(1, 0) // subnested
+
+ ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, 'I', 0)) // ignore subnested
+
+ row, _ := ui.table.GetSelection()
+ assert.Equal(t, 2, row) // selection moves to next row
+
+ ui.table.Select(1, 0)
+ ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, 'I', 0)) // unignore subnested
+}
+
func TestEmptyFile(t *testing.T) {
fin := testdir.CreateTestDir()
defer fin()
diff --git a/tui/show.go b/tui/show.go
index 39923a1..0beeeff 100644
--- a/tui/show.go
+++ b/tui/show.go
@@ -31,6 +31,7 @@ Item under cursor:
[::b]d [white:black:-]Delete file or directory
[::b]e [white:black:-]Empty file or directory
[::b]space [white:black:-]Mark file or directory for deletion
+ [::b]I [white:black:-]Ignore file or directory
[::b]v [white:black:-]Show content of file
[::b]o [white:black:-]Open file or directory in external program
[::b]i [white:black:-]Show info about item
@@ -87,18 +88,27 @@ func (ui *UI) showDir() {
unlock := ui.currentDir.RLock()
defer unlock()
- if ui.ShowRelativeSize {
- for _, item := range ui.currentDir.GetFiles() {
+ i := rowIndex
+ maxUsage = 0
+ maxSize = 0
+ for _, item := range ui.currentDir.GetFiles() {
+ if _, ignored := ui.ignoredRows[i]; ignored {
+ i++
+ continue
+ }
+
+ if ui.ShowRelativeSize {
if item.GetUsage() > maxUsage {
maxUsage = item.GetUsage()
}
if item.GetSize() > maxSize {
maxSize = item.GetSize()
}
+ } else {
+ maxSize += item.GetSize()
+ maxUsage += item.GetUsage()
}
- } else {
- maxUsage = ui.currentDir.GetUsage()
- maxSize = ui.currentDir.GetSize()
+ i++
}
for i, item := range ui.currentDir.GetFiles() {
@@ -109,15 +119,21 @@ func (ui *UI) showDir() {
continue
}
- totalUsage += item.GetUsage()
- totalSize += item.GetSize()
- itemCount += item.GetItemCount()
+ _, ignored := ui.ignoredRows[rowIndex]
+
+ if !ignored {
+ totalUsage += item.GetUsage()
+ totalSize += item.GetSize()
+ itemCount += item.GetItemCount()
+ }
_, marked := ui.markedRows[rowIndex]
- cell := tview.NewTableCell(ui.formatFileRow(item, maxUsage, maxSize, marked))
+ cell := tview.NewTableCell(ui.formatFileRow(item, maxUsage, maxSize, marked, ignored))
cell.SetReference(ui.currentDir.GetFiles()[i])
- if marked {
+ if ignored {
+ cell.SetStyle(tcell.Style{}.Foreground(tview.Styles.SecondaryTextColor))
+ } else if marked {
cell.SetStyle(tcell.Style{}.Foreground(tview.Styles.PrimaryTextColor))
cell.SetBackgroundColor(tview.Styles.ContrastBackgroundColor)
} else {
diff --git a/tui/tui.go b/tui/tui.go
index 57edb98..a737866 100644
--- a/tui/tui.go
+++ b/tui/tui.go
@@ -61,6 +61,7 @@ type UI struct {
useOldSizeBar bool
defaultSortBy string
defaultSortOrder string
+ ignoredRows map[int]struct{}
markedRows map[int]struct{}
exportName string
noDelete bool
@@ -115,6 +116,7 @@ func CreateUI(
currentItemNameMaxLen: 70,
defaultSortBy: "size",
defaultSortOrder: "desc",
+ ignoredRows: make(map[int]struct{}),
markedRows: make(map[int]struct{}),
exportName: "export.json",
noDelete: false,
@@ -282,6 +284,7 @@ func (ui *UI) fileItemSelected(row, column int) {
ui.currentDir = selectedDir
ui.hideFilterInput()
ui.markedRows = make(map[int]struct{})
+ ui.ignoredRows = make(map[int]struct{})
ui.showDir()
if origDir.GetParent() != nil && selectedDir.GetName() == origDir.GetParent().GetName() {
diff --git a/tui/tui_test.go b/tui/tui_test.go
index abf3d95..46821ec 100644
--- a/tui/tui_test.go
+++ b/tui/tui_test.go
@@ -97,7 +97,7 @@ func TestHelp(t *testing.T) {
b, _, _ := simScreen.GetContents()
- cells := b[456 : 456+9]
+ cells := b[507 : 507+9]
text := []byte("directory")
for i, r := range cells {
@@ -118,7 +118,7 @@ func TestHelpBw(t *testing.T) {
b, _, _ := simScreen.GetContents()
- cells := b[456 : 456+9]
+ cells := b[507 : 507+9]
text := []byte("directory")
for i, r := range cells {