add filter to table

This commit is contained in:
Lilian Jónsdóttir 2024-07-30 18:32:34 -07:00
parent 3e195f0d73
commit ed2def9c2f
3 changed files with 139 additions and 12 deletions

1
go.mod
View file

@ -11,6 +11,7 @@ require (
github.com/charmbracelet/log v0.4.0 github.com/charmbracelet/log v0.4.0
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/ijt/go-anytime v1.9.2 github.com/ijt/go-anytime v1.9.2
github.com/lithammer/fuzzysearch v1.1.8
github.com/urfave/cli/v2 v2.27.3 github.com/urfave/cli/v2 v2.27.3
gitlab.com/tymonx/go-formatter v1.5.1 gitlab.com/tymonx/go-formatter v1.5.1
golang.org/x/term v0.22.0 golang.org/x/term v0.22.0

29
go.sum
View file

@ -45,6 +45,8 @@ github.com/ijt/go-anytime v1.9.2 h1:DmYgVwUiFPNR+n6c1T5P070tlGATRZG4aYNJs6XDUfU=
github.com/ijt/go-anytime v1.9.2/go.mod h1:egBT6FhVjNlXNHUN2wTPi6ILCNKXeeXFy04pWJjw/LI= github.com/ijt/go-anytime v1.9.2/go.mod h1:egBT6FhVjNlXNHUN2wTPi6ILCNKXeeXFy04pWJjw/LI=
github.com/ijt/goparsify v0.0.0-20221203142333-3a5276334b8d h1:LFOmpWrSbtolg0YqYC9hQjj5WSLtRGb6aZ3JAugLfgg= github.com/ijt/goparsify v0.0.0-20221203142333-3a5276334b8d h1:LFOmpWrSbtolg0YqYC9hQjj5WSLtRGb6aZ3JAugLfgg=
github.com/ijt/goparsify v0.0.0-20221203142333-3a5276334b8d/go.mod h1:112TOyA+aruNSUBlyBWlKBdLVYTdhjiO2CKD0j/URSU= github.com/ijt/goparsify v0.0.0-20221203142333-3a5276334b8d/go.mod h1:112TOyA+aruNSUBlyBWlKBdLVYTdhjiO2CKD0j/URSU=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
@ -81,27 +83,54 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitlab.com/tymonx/go-formatter v1.5.1 h1:gmn5rJqR6LlI1DkpBmiCo0MZ3ges581A14GZcXlGe60= gitlab.com/tymonx/go-formatter v1.5.1 h1:gmn5rJqR6LlI1DkpBmiCo0MZ3ges581A14GZcXlGe60=
gitlab.com/tymonx/go-formatter v1.5.1/go.mod h1:z1E064wx+cgg5ChY+1E+hrJf8uKY//kF1Q1As+w5WRQ= gitlab.com/tymonx/go-formatter v1.5.1/go.mod h1:z1E064wx+cgg5ChY+1E+hrJf8uKY//kF1Q1As+w5WRQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View file

@ -18,6 +18,7 @@ import (
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/lithammer/fuzzysearch/fuzzy"
) )
const ( const (
@ -71,12 +72,15 @@ type model struct {
selectsize int64 selectsize int64
readonly bool readonly bool
once bool once bool
filtering bool
filter string
termheight int termheight int
termwidth int termwidth int
mode modes.Mode mode modes.Mode
sorting sorting.Sorting sorting sorting.Sorting
workdir string workdir string
files files.Files files files.Files
fltrfiles files.Files
} }
func newModel(fls []files.File, width, height int, readonly, once bool, workdir string, mode modes.Mode) model { func newModel(fls []files.File, width, height int, readonly, once bool, workdir string, mode modes.Mode) model {
@ -145,6 +149,10 @@ type keyMap struct {
clen key.Binding clen key.Binding
sort key.Binding sort key.Binding
rort key.Binding rort key.Binding
fltr key.Binding
clfl key.Binding
apfl key.Binding
bksp key.Binding
quit key.Binding quit key.Binding
} }
@ -186,6 +194,22 @@ func defaultKeyMap() keyMap {
key.WithKeys("S"), key.WithKeys("S"),
key.WithHelp("S", "sort (reverse)"), key.WithHelp("S", "sort (reverse)"),
), ),
fltr: key.NewBinding(
key.WithKeys("/"),
key.WithHelp("/", "filter"),
),
apfl: key.NewBinding(
key.WithKeys("enter"),
key.WithHelp("enter", "apply filter"),
),
clfl: key.NewBinding(
key.WithKeys("esc"),
key.WithHelp("esc", "clear filter"),
),
bksp: key.NewBinding(
key.WithKeys("backspace"),
key.WithHelp("backspace", "backspace"),
),
quit: key.NewBinding( quit: key.NewBinding(
key.WithKeys("q", "ctrl+c"), key.WithKeys("q", "ctrl+c"),
key.WithHelp("q", "quit"), key.WithHelp("q", "quit"),
@ -211,6 +235,24 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyMsg:
if m.filtering {
switch {
case key.Matches(msg, m.keys.clfl):
m.filter = ""
m.filtering = false
case key.Matches(msg, m.keys.apfl):
m.filtering = false
case key.Matches(msg, m.keys.bksp):
if len(m.filter) > 0 {
m.filter = m.filter[:len(m.filter)-1]
}
default:
m.filter += msg.String()
}
m.applyFilter()
return m, cmd
}
switch { switch {
case key.Matches(msg, m.keys.mark): case key.Matches(msg, m.keys.mark):
m.toggleItem(m.table.Cursor()) m.toggleItem(m.table.Cursor())
@ -234,6 +276,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keys.rort): case key.Matches(msg, m.keys.rort):
m.sorting = m.sorting.Prev() m.sorting = m.sorting.Prev()
m.sort() m.sort()
case key.Matches(msg, m.keys.fltr):
m.filtering = true
case key.Matches(msg, m.keys.clfl):
m.filter = ""
m.applyFilter()
case key.Matches(msg, m.keys.quit): case key.Matches(msg, m.keys.quit):
return m.quit(true) return m.quit(true)
} }
@ -245,22 +292,26 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
func (m model) View() string { func (m model) View() string {
var panels []string return lipgloss.JoinVertical(lipgloss.Top,
m.header(),
if m.mode != modes.Listing { style.Render(m.table.View()),
panels = append(panels, m.header()) m.footer(),
} )
panels = append(panels, style.Render(m.table.View()), m.footer())
return lipgloss.JoinVertical(lipgloss.Top, panels...)
} }
func (m model) showHelp() string { func (m model) showHelp() string {
// TODO: maybe use bubbletea built in help // TODO: maybe use bubbletea built in help
var keys = []string{ var filterText string
if m.filter != "" {
filterText = fmt.Sprintf(" (%s)", m.filter)
}
keys := []string{
fmt.Sprintf("%s %s%s", darktext.Render(m.keys.fltr.Help().Key), darkertext.Render(m.keys.fltr.Help().Desc), filterText),
fmt.Sprintf("%s %s (%s)", darktext.Render(m.keys.sort.Help().Key), darkertext.Render(m.keys.sort.Help().Desc), m.sorting.String()), fmt.Sprintf("%s %s (%s)", darktext.Render(m.keys.sort.Help().Key), darkertext.Render(m.keys.sort.Help().Desc), m.sorting.String()),
styleKey(m.keys.quit), styleKey(m.keys.quit),
} }
if !m.readonly { if !m.readonly {
if m.mode != modes.Interactive { if m.mode != modes.Interactive {
keys = append([]string{ keys = append([]string{
@ -275,6 +326,7 @@ func (m model) showHelp() string {
} }
func (m model) header() string { func (m model) header() string {
// TODO: clean this ugly thing up
var ( var (
right, left string right, left string
spacerWidth int spacerWidth int
@ -287,6 +339,10 @@ func (m model) header() string {
styleKey(m.keys.nada), styleKey(m.keys.nada),
styleKey(m.keys.invr), styleKey(m.keys.invr),
} }
filterKeys = []string{
styleKey(m.keys.clfl),
styleKey(m.keys.apfl),
}
dot = darkesttext.Render("•") dot = darkesttext.Render("•")
wideDot = darkesttext.Render(" • ") wideDot = darkesttext.Render(" • ")
) )
@ -305,6 +361,19 @@ func (m model) header() string {
left = fmt.Sprintf("%d/%d %s %s", len(m.selected), len(m.table.Rows()), dot, humanize.Bytes(uint64(m.selectsize))) left = fmt.Sprintf("%d/%d %s %s", len(m.selected), len(m.table.Rows()), dot, humanize.Bytes(uint64(m.selectsize)))
if m.mode == modes.Listing {
title := "Showing"
if m.filter != "" || m.filtering {
title += " (filtered)"
}
right = fmt.Sprintf(" %s %d files in trash", title, len(m.table.Rows()))
left = ""
}
if m.filtering {
right = fmt.Sprintf(" Filtering %s %s", dot, strings.Join(filterKeys, wideDot))
}
// offset of 2 again because of table border // offset of 2 again because of table border
spacerWidth = m.termwidth - lipgloss.Width(right) - lipgloss.Width(left) - poffset spacerWidth = m.termwidth - lipgloss.Width(right) - lipgloss.Width(left) - poffset
if spacerWidth <= 0 { if spacerWidth <= 0 {
@ -447,8 +516,8 @@ func (m *model) selectAll() {
m.selected = map[string]bool{} m.selected = map[string]bool{}
m.selectsize = 0 m.selectsize = 0
for i := range m.table.Rows() { for i := range m.table.Rows() {
m.selected[m.files[i].String()] = true m.selected[m.fltrfiles[i].String()] = true
m.selectsize += m.files[i].Filesize() m.selectsize += m.fltrfiles[i].Filesize()
} }
m.updateRows(true) m.updateRows(true)
} }
@ -501,8 +570,13 @@ func (m *model) invertSelection() {
func (m *model) sort() { func (m *model) sort() {
slices.SortStableFunc(m.files, m.sorting.Sorter()) slices.SortStableFunc(m.files, m.sorting.Sorter())
m.applyFilter()
}
func (m *model) applyFilter() {
m.fltrfiles = m.filteredFiles()
var rows = []table.Row{} var rows = []table.Row{}
for _, file := range m.files { for _, file := range m.fltrfiles {
r := newRow(file, m.workdir) r := newRow(file, m.workdir)
if !m.readonly { if !m.readonly {
r = append(r, getCheck(m.selected[file.String()])) r = append(r, getCheck(m.selected[file.String()]))
@ -511,6 +585,29 @@ func (m *model) sort() {
} }
m.table.SetRows(rows) m.table.SetRows(rows)
m.updateTableHeight()
}
func (m *model) filteredFiles() (filteredFiles files.Files) {
for _, file := range m.files {
if fuzzy.Match(m.filter, file.Name()) {
filteredFiles = append(filteredFiles, file)
} else {
if _, ok := m.selected[file.String()]; ok {
delete(m.selected, file.String())
m.selectsize -= file.Filesize()
}
}
}
return
}
func (m *model) updateTableHeight() {
h := min(m.termheight-hoffset, len(m.table.Rows()))
m.table.SetHeight(h)
if m.table.Cursor() >= h {
m.table.SetCursor(h - 1)
}
} }
func Select(fls files.Files, width, height int, readonly, once bool, workdir string, mode modes.Mode) (files.Files, modes.Mode, error) { func Select(fls files.Files, width, height int, readonly, once bool, workdir string, mode modes.Mode) (files.Files, modes.Mode, error) {