- Fixed the 'M' bind to mark all/none items, rather than toggle - Fixed panic which was raised when reqesting @item with an index beyond the length of resultset - Added changing the table when calling @table with a table or string name
This commit is contained in:
parent
85a4f0b5e9
commit
c8b65f6b0a
|
|
@ -154,6 +154,40 @@ func TestModRS_Query(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestModRS_Filter(t *testing.T) {
|
||||
tests := []struct {
|
||||
descr string
|
||||
cmd string
|
||||
}{
|
||||
{
|
||||
descr: "returns filtered items 1",
|
||||
cmd: `
|
||||
rs = rs:scan -table service-test-data
|
||||
rs = rs:filter $rs 'pk="abc"'
|
||||
assert (len $rs) "expected len == 2"
|
||||
assert (eq $rs.First.pk "abc") "expected First.pk == abc"
|
||||
`,
|
||||
},
|
||||
//{
|
||||
// descr: "returns filtered items 2",
|
||||
// cmd: `
|
||||
// rs = rs:scan -table service-test-data
|
||||
// rs = rs:filter $rs 'pk="bbb"'
|
||||
// assert (len $rs) "expected len == 1"
|
||||
// assert (eq $rs.First.pk "bbb") "expected First.pk == bbb"
|
||||
// `,
|
||||
//},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.descr, func(t *testing.T) {
|
||||
svc := newService(t)
|
||||
|
||||
_, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestModRS_First(t *testing.T) {
|
||||
tests := []struct {
|
||||
descr string
|
||||
|
|
|
|||
|
|
@ -174,6 +174,31 @@ func (tp resultSetItemsProxy) Index(k int) ucl.Object {
|
|||
return itemProxy{resultSet: tp.resultSet, idx: k, item: tp.resultSet.Items()[k]}
|
||||
}
|
||||
|
||||
type resultSetMarkedItemsProxy struct {
|
||||
resultSet *models.ResultSet
|
||||
}
|
||||
|
||||
func (ip resultSetMarkedItemsProxy) String() string {
|
||||
return fmt.Sprintf("MarkedItems(%v)", len(ip.resultSet.MarkedItems()))
|
||||
}
|
||||
|
||||
func (ip resultSetMarkedItemsProxy) Truthy() bool {
|
||||
return len(ip.resultSet.MarkedItems()) > 0
|
||||
}
|
||||
|
||||
func (tp resultSetMarkedItemsProxy) Len() int {
|
||||
return len(tp.resultSet.MarkedItems())
|
||||
}
|
||||
|
||||
func (tp resultSetMarkedItemsProxy) Index(k int) ucl.Object {
|
||||
markedItems := tp.resultSet.MarkedItems()
|
||||
if k >= len(markedItems) {
|
||||
return nil
|
||||
}
|
||||
actualItem := tp.resultSet.Items()[markedItems[k].Index]
|
||||
return itemProxy{resultSet: tp.resultSet, idx: markedItems[k].Index, item: actualItem}
|
||||
}
|
||||
|
||||
type itemProxy struct {
|
||||
resultSet *models.ResultSet
|
||||
idx int
|
||||
|
|
|
|||
|
|
@ -2,20 +2,53 @@ package cmdpacks
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/controllers"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models"
|
||||
"github.com/pkg/errors"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/tables"
|
||||
)
|
||||
|
||||
type tablePVar struct {
|
||||
state *controllers.State
|
||||
state *controllers.State
|
||||
tableService *tables.Service
|
||||
readController *controllers.TableReadController
|
||||
}
|
||||
|
||||
func (rs tablePVar) Get(ctx context.Context) (any, error) {
|
||||
return newTableProxy(rs.state.ResultSet().TableInfo), nil
|
||||
}
|
||||
|
||||
func (rs tablePVar) Set(ctx context.Context, value any) error {
|
||||
scanNewTable := func(name string) error {
|
||||
tableInfo, err := rs.tableService.Describe(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "cannot describe %v", name)
|
||||
}
|
||||
|
||||
resultSet, err := rs.tableService.Scan(ctx, tableInfo)
|
||||
if resultSet != nil {
|
||||
resultSet = rs.tableService.Filter(resultSet, rs.state.Filter())
|
||||
}
|
||||
|
||||
msg := rs.readController.SetResultSet(resultSet)
|
||||
commandctrl.PostMsg(ctx, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
tblVal, ok := value.(SimpleProxy[*models.TableInfo])
|
||||
if ok {
|
||||
return scanNewTable(tblVal.value.Name)
|
||||
}
|
||||
|
||||
strVal, ok := value.(string)
|
||||
if ok {
|
||||
return scanNewTable(strVal)
|
||||
}
|
||||
return errors.New("new value to @table is not a table name")
|
||||
}
|
||||
|
||||
type resultSetPVar struct {
|
||||
state *controllers.State
|
||||
readController *controllers.TableReadController
|
||||
|
|
@ -36,6 +69,15 @@ func (rs resultSetPVar) Set(ctx context.Context, value any) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type markedSetPVar struct {
|
||||
state *controllers.State
|
||||
readController *controllers.TableReadController
|
||||
}
|
||||
|
||||
func (rs markedSetPVar) Get(ctx context.Context) (any, error) {
|
||||
return resultSetMarkedItemsProxy{rs.state.ResultSet()}, nil
|
||||
}
|
||||
|
||||
type itemPVar struct {
|
||||
state *controllers.State
|
||||
}
|
||||
|
|
@ -43,9 +85,14 @@ type itemPVar struct {
|
|||
func (rs itemPVar) Get(ctx context.Context) (any, error) {
|
||||
selItem, ok := commandctrl.SelectedItemIndex(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("no item selected")
|
||||
return nil, nil
|
||||
}
|
||||
return itemProxy{rs.state.ResultSet(), selItem, rs.state.ResultSet().Items()[selItem]}, nil
|
||||
rset := rs.state.ResultSet()
|
||||
if selItem < 0 || selItem >= len(rs.state.ResultSet().Items()) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return itemProxy{rset, selItem, rset.Items()[selItem]}, nil
|
||||
}
|
||||
|
||||
func (rs itemPVar) Set(ctx context.Context, value any) error {
|
||||
|
|
|
|||
32
internal/common/ui/commandctrl/cmdpacks/pvars_test.go
Normal file
32
internal/common/ui/commandctrl/cmdpacks/pvars_test.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package cmdpacks_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPVars(t *testing.T) {
|
||||
tests := []struct {
|
||||
descr string
|
||||
cmd string
|
||||
}{
|
||||
{
|
||||
descr: "returns item on empty result set",
|
||||
cmd: `
|
||||
ui:query '"a"="1"' -table service-test-data
|
||||
@item
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.descr, func(t *testing.T) {
|
||||
svc := newService(t)
|
||||
|
||||
ctx := t.Context()
|
||||
|
||||
_, err := svc.CommandController.ExecuteAndWait(ctx, tt.cmd)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package cmdpacks
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/pkg/errors"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl"
|
||||
|
|
@ -426,8 +427,9 @@ func (sc StandardCommands) ConfigureUCL(ucl *ucl.Inst) {
|
|||
ucl.SetBuiltin("q", sc.cmdQuit)
|
||||
|
||||
ucl.SetPseudoVar("resultset", resultSetPVar{sc.State, sc.ReadController})
|
||||
ucl.SetPseudoVar("table", tablePVar{sc.State})
|
||||
ucl.SetPseudoVar("table", tablePVar{sc.State, sc.TableService, sc.ReadController})
|
||||
ucl.SetPseudoVar("item", itemPVar{sc.State})
|
||||
ucl.SetPseudoVar("marked", markedSetPVar{sc.State, sc.ReadController})
|
||||
}
|
||||
|
||||
func (sc StandardCommands) RunPrelude(ctx context.Context, ucl *ucl.Inst) error {
|
||||
|
|
@ -438,4 +440,13 @@ func (sc StandardCommands) RunPrelude(ctx context.Context, ucl *ucl.Inst) error
|
|||
const uclPrelude = `
|
||||
ui:command unmark { mark none }
|
||||
ui:command set-opt { |n k| opt:set $n $k }
|
||||
|
||||
ui:bind "view.toggle-marked-items" "M" {
|
||||
markedCount = len @marked
|
||||
if (eq $markedCount (len @resultset)) {
|
||||
mark none
|
||||
} else {
|
||||
mark all
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
bus "github.com/lmika/events"
|
||||
"github.com/pkg/errors"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/common/ui/events"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models/attrcodec"
|
||||
|
|
@ -20,8 +22,6 @@ import (
|
|||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/inputhistory"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/itemrenderer"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/viewsnapshot"
|
||||
bus "github.com/lmika/events"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type resultSetUpdateOp int
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
)
|
||||
|
||||
type ResultSet struct {
|
||||
|
|
@ -20,6 +22,10 @@ type ResultSet struct {
|
|||
|
||||
columns []string
|
||||
sortCriteria SortCriteria
|
||||
|
||||
mutex sync.Mutex
|
||||
cachedMarkedItems []ItemIndex
|
||||
hasCachedMarkedItems bool
|
||||
}
|
||||
|
||||
type Queryable interface {
|
||||
|
|
@ -47,6 +53,11 @@ func (rs *ResultSet) Items() []Item {
|
|||
func (rs *ResultSet) SetItems(items []Item) {
|
||||
rs.items = items
|
||||
rs.attributes = make([]ItemAttribute, len(items))
|
||||
|
||||
rs.mutex.Lock()
|
||||
defer rs.mutex.Unlock()
|
||||
rs.hasCachedMarkedItems = false
|
||||
rs.cachedMarkedItems = nil
|
||||
}
|
||||
|
||||
func (rs *ResultSet) SortCriteria() SortCriteria {
|
||||
|
|
@ -56,10 +67,24 @@ func (rs *ResultSet) SortCriteria() SortCriteria {
|
|||
func (rs *ResultSet) AddNewItem(item Item, attrs ItemAttribute) {
|
||||
rs.items = append(rs.items, item)
|
||||
rs.attributes = append(rs.attributes, attrs)
|
||||
|
||||
rs.mutex.Lock()
|
||||
defer rs.mutex.Unlock()
|
||||
rs.hasCachedMarkedItems = false
|
||||
rs.cachedMarkedItems = nil
|
||||
}
|
||||
|
||||
func (rs *ResultSet) SetMark(idx int, marked bool) {
|
||||
rs.attributes[idx].Marked = marked
|
||||
|
||||
if !rs.hasCachedMarkedItems {
|
||||
return
|
||||
}
|
||||
|
||||
rs.mutex.Lock()
|
||||
defer rs.mutex.Unlock()
|
||||
rs.hasCachedMarkedItems = false
|
||||
rs.cachedMarkedItems = nil
|
||||
}
|
||||
|
||||
func (rs *ResultSet) SetHidden(idx int, hidden bool) {
|
||||
|
|
@ -91,12 +116,20 @@ func (rs *ResultSet) IsNew(idx int) bool {
|
|||
}
|
||||
|
||||
func (rs *ResultSet) MarkedItems() []ItemIndex {
|
||||
rs.mutex.Lock()
|
||||
defer rs.mutex.Unlock()
|
||||
if rs.hasCachedMarkedItems {
|
||||
return rs.cachedMarkedItems
|
||||
}
|
||||
|
||||
items := make([]ItemIndex, 0)
|
||||
for i, itemAttr := range rs.attributes {
|
||||
if itemAttr.Marked && !itemAttr.Hidden {
|
||||
items = append(items, ItemIndex{Index: i, Item: rs.items[i]})
|
||||
}
|
||||
}
|
||||
rs.cachedMarkedItems = items
|
||||
rs.hasCachedMarkedItems = true
|
||||
return items
|
||||
}
|
||||
|
||||
|
|
|
|||
183
internal/dynamo-browse/models/models_test.go
Normal file
183
internal/dynamo-browse/models/models_test.go
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMarkedItems(t *testing.T) {
|
||||
t.Run("SetMark properly reflected in MarkedItems", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
})
|
||||
|
||||
// Initially, no items should be marked
|
||||
assert.Len(t, rs.MarkedItems(), 0)
|
||||
|
||||
// Mark the first item
|
||||
rs.SetMark(0, true)
|
||||
markedItems := rs.MarkedItems()
|
||||
assert.Len(t, markedItems, 1)
|
||||
assert.Equal(t, 0, markedItems[0].Index)
|
||||
|
||||
// Mark the third item
|
||||
rs.SetMark(2, true)
|
||||
markedItems = rs.MarkedItems()
|
||||
assert.Len(t, markedItems, 2)
|
||||
assert.Equal(t, 0, markedItems[0].Index)
|
||||
assert.Equal(t, 2, markedItems[1].Index)
|
||||
|
||||
// Verify the items themselves are correct
|
||||
item1, ok1 := markedItems[0].Item.AttributeValueAsString("id")
|
||||
item2, ok2 := markedItems[1].Item.AttributeValueAsString("id")
|
||||
assert.True(t, ok1)
|
||||
assert.True(t, ok2)
|
||||
assert.Equal(t, "item1", item1)
|
||||
assert.Equal(t, "item3", item2)
|
||||
})
|
||||
|
||||
t.Run("item with Marked=true is in MarkedItems", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
})
|
||||
|
||||
// Directly set the Marked attribute to true for item at index 1
|
||||
rs.SetMark(1, true)
|
||||
|
||||
markedItems := rs.MarkedItems()
|
||||
assert.Len(t, markedItems, 1)
|
||||
assert.Equal(t, 1, markedItems[0].Index)
|
||||
|
||||
item, ok := markedItems[0].Item.AttributeValueAsString("id")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "item2", item)
|
||||
})
|
||||
|
||||
t.Run("adding marked items affects result of MarkedItems", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
})
|
||||
|
||||
// Mark all items
|
||||
rs.SetMark(0, true)
|
||||
rs.SetMark(1, true)
|
||||
assert.Len(t, rs.MarkedItems(), 2)
|
||||
|
||||
markedItems := rs.MarkedItems()
|
||||
expectedIndices := []int{0, 1}
|
||||
for i, expected := range expectedIndices {
|
||||
assert.Equal(t, expected, markedItems[i].Index)
|
||||
}
|
||||
|
||||
// Add a new unmarked item
|
||||
rs.AddNewItem(Item{"id": &types.AttributeValueMemberS{Value: "item4"}}, ItemAttribute{})
|
||||
assert.Len(t, rs.MarkedItems(), 2)
|
||||
|
||||
// Add a new marked item
|
||||
rs.AddNewItem(Item{"id": &types.AttributeValueMemberS{Value: "item5"}}, ItemAttribute{Marked: true})
|
||||
assert.Len(t, rs.MarkedItems(), 3)
|
||||
|
||||
markedItems = rs.MarkedItems()
|
||||
expectedIndices = []int{0, 1, 4}
|
||||
for i, expected := range expectedIndices {
|
||||
assert.Equal(t, expected, markedItems[i].Index)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("changing SetMark updates length of MarkedItems", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item4"}},
|
||||
})
|
||||
|
||||
// Mark all items
|
||||
rs.SetMark(0, true)
|
||||
rs.SetMark(1, true)
|
||||
rs.SetMark(2, true)
|
||||
rs.SetMark(3, true)
|
||||
assert.Len(t, rs.MarkedItems(), 4)
|
||||
|
||||
// Unmark one item
|
||||
rs.SetMark(1, false)
|
||||
assert.Len(t, rs.MarkedItems(), 3)
|
||||
|
||||
// Verify the correct items are marked
|
||||
markedItems := rs.MarkedItems()
|
||||
expectedIndices := []int{0, 2, 3}
|
||||
for i, expected := range expectedIndices {
|
||||
assert.Equal(t, expected, markedItems[i].Index)
|
||||
}
|
||||
|
||||
// Unmark all remaining items
|
||||
rs.SetMark(0, false)
|
||||
rs.SetMark(2, false)
|
||||
rs.SetMark(3, false)
|
||||
assert.Len(t, rs.MarkedItems(), 0)
|
||||
})
|
||||
|
||||
t.Run("changing items clears all marked items", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
})
|
||||
|
||||
// Mark all items
|
||||
rs.SetMark(0, true)
|
||||
rs.SetMark(1, true)
|
||||
rs.SetMark(2, true)
|
||||
assert.Len(t, rs.MarkedItems(), 3)
|
||||
|
||||
// Call SetItems with new items
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "newitem1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "newitem2"}},
|
||||
})
|
||||
|
||||
// All marks should be cleared
|
||||
assert.Len(t, rs.MarkedItems(), 0)
|
||||
|
||||
// Verify none of the new items are marked
|
||||
assert.False(t, rs.Marked(0))
|
||||
assert.False(t, rs.Marked(1))
|
||||
})
|
||||
|
||||
t.Run("hidden items are excluded from MarkedItems", func(t *testing.T) {
|
||||
rs := &ResultSet{}
|
||||
rs.SetItems([]Item{
|
||||
{"id": &types.AttributeValueMemberS{Value: "item1"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item2"}},
|
||||
{"id": &types.AttributeValueMemberS{Value: "item3"}},
|
||||
})
|
||||
|
||||
// Mark all items
|
||||
rs.SetMark(0, true)
|
||||
rs.SetMark(1, true)
|
||||
rs.SetMark(2, true)
|
||||
|
||||
// Hide the second item
|
||||
rs.SetHidden(1, true)
|
||||
|
||||
markedItems := rs.MarkedItems()
|
||||
assert.Len(t, markedItems, 2)
|
||||
|
||||
// Verify only items 0 and 2 are in the marked items
|
||||
assert.Equal(t, 0, markedItems[0].Index)
|
||||
assert.Equal(t, 2, markedItems[1].Index)
|
||||
})
|
||||
}
|
||||
|
|
@ -10,8 +10,8 @@ import (
|
|||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models/queryexpr"
|
||||
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models"
|
||||
)
|
||||
|
||||
func TestModExpr_Query(t *testing.T) {
|
||||
|
|
@ -502,6 +502,9 @@ func TestQueryExpr_EvalItem(t *testing.T) {
|
|||
{expr: `alpha^="al"`, expected: &types.AttributeValueMemberBOOL{Value: true}},
|
||||
{expr: `alpha="foobar"`, expected: &types.AttributeValueMemberBOOL{Value: false}},
|
||||
{expr: `alpha^="need-something"`, expected: &types.AttributeValueMemberBOOL{Value: false}},
|
||||
{expr: `""=""`, expected: &types.AttributeValueMemberBOOL{Value: true}},
|
||||
{expr: `"abc"="abc"`, expected: &types.AttributeValueMemberBOOL{Value: true}},
|
||||
{expr: `""="abc"`, expected: &types.AttributeValueMemberBOOL{Value: false}},
|
||||
|
||||
// Comparison
|
||||
{expr: "three > 4", expected: &types.AttributeValueMemberBOOL{Value: false}},
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ func Default() *KeyBindings {
|
|||
},
|
||||
View: &ViewKeyBindings{
|
||||
Mark: key.NewBinding(key.WithKeys("m"), key.WithHelp("m", "mark")),
|
||||
ToggleMarkedItems: key.NewBinding(key.WithKeys("M"), key.WithHelp("M", "toggle marged items")),
|
||||
CopyItemToClipboard: key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "copy item to clipboard")),
|
||||
CopyTableToClipboard: key.NewBinding(key.WithKeys("C"), key.WithHelp("C", "copy table to clipboard")),
|
||||
Rescan: key.NewBinding(key.WithKeys("R"), key.WithHelp("R", "rescan")),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ type TableKeyBinding struct {
|
|||
|
||||
type ViewKeyBindings struct {
|
||||
Mark key.Binding `keymap:"mark"`
|
||||
ToggleMarkedItems key.Binding `keymap:"toggle-marked-items"`
|
||||
CopyItemToClipboard key.Binding `keymap:"copy-item-to-clipboard"`
|
||||
CopyTableToClipboard key.Binding `keymap:"copy-table-to-clipboard"`
|
||||
Rescan key.Binding `keymap:"rescan"`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
bus "github.com/lmika/events"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/common/ui/events"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/controllers"
|
||||
|
|
@ -20,8 +23,6 @@ import (
|
|||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/ui/teamodels/styles"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/ui/teamodels/tableselect"
|
||||
"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/ui/teamodels/utils"
|
||||
bus "github.com/lmika/events"
|
||||
"log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -125,8 +126,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
if idx := m.tableView.SelectedItemIndex(); idx >= 0 {
|
||||
return m, events.SetTeaMessage(m.tableWriteController.ToggleMark(idx))
|
||||
}
|
||||
case key.Matches(msg, m.keyMap.ToggleMarkedItems):
|
||||
return m, events.SetTeaMessage(m.tableReadController.Mark(controllers.MarkOpToggle, ""))
|
||||
case key.Matches(msg, m.keyMap.CopyItemToClipboard):
|
||||
if idx := m.tableView.SelectedItemIndex(); idx >= 0 {
|
||||
return m, events.SetTeaMessage(m.tableReadController.CopyItemToClipboard(idx))
|
||||
|
|
|
|||
Loading…
Reference in a new issue