Almost feature complete
- Added reading of UCL scripts - Added pasteboard commands - Added ui:command which will define a proc at the top-level
This commit is contained in:
parent
7ae99b009b
commit
cae7509a76
|
@ -8,6 +8,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/config"
|
"github.com/aws/aws-sdk-go-v2/config"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
||||||
|
@ -45,6 +46,7 @@ func main() {
|
||||||
var flagDefaultLimit = flag.Int("default-limit", 0, "default limit for queries and scans")
|
var flagDefaultLimit = flag.Int("default-limit", 0, "default limit for queries and scans")
|
||||||
var flagWorkspace = flag.String("w", "", "workspace file")
|
var flagWorkspace = flag.String("w", "", "workspace file")
|
||||||
var flagQuery = flag.String("q", "", "run query")
|
var flagQuery = flag.String("q", "", "run query")
|
||||||
|
var flagExtDir = flag.String("ext-dir", "$HOME/.config/dynamo-browse/ext:$HOME/.config/dynamo-browse/.", "directory to search for extensions")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -128,7 +130,7 @@ func main() {
|
||||||
exportController := controllers.NewExportController(state, tableService, jobsController, columnsController, pasteboardProvider)
|
exportController := controllers.NewExportController(state, tableService, jobsController, columnsController, pasteboardProvider)
|
||||||
settingsController := controllers.NewSettingsController(settingStore, eventBus)
|
settingsController := controllers.NewSettingsController(settingStore, eventBus)
|
||||||
keyBindings := keybindings.Default()
|
keyBindings := keybindings.Default()
|
||||||
scriptController := controllers.NewScriptController(scriptManagerService, tableReadController, jobsController, settingsController, eventBus)
|
//scriptController := controllers.NewScriptController(scriptManagerService, tableReadController, jobsController, settingsController, eventBus)
|
||||||
|
|
||||||
if *flagQuery != "" {
|
if *flagQuery != "" {
|
||||||
if *flagTable == "" {
|
if *flagTable == "" {
|
||||||
|
@ -167,10 +169,11 @@ func main() {
|
||||||
tableWriteController,
|
tableWriteController,
|
||||||
exportController,
|
exportController,
|
||||||
keyBindingController,
|
keyBindingController,
|
||||||
|
pasteboardProvider,
|
||||||
)
|
)
|
||||||
|
|
||||||
commandController := commandctrl.NewCommandController(inputHistoryService, stdCommands)
|
commandController := commandctrl.NewCommandController(inputHistoryService, stdCommands)
|
||||||
commandController.AddCommandLookupExtension(scriptController)
|
//commandController.AddCommandLookupExtension(scriptController)
|
||||||
commandController.SetCommandCompletionProvider(columnsController)
|
commandController.SetCommandCompletionProvider(columnsController)
|
||||||
|
|
||||||
model := ui.NewModel(
|
model := ui.NewModel(
|
||||||
|
@ -182,7 +185,7 @@ func main() {
|
||||||
jobsController,
|
jobsController,
|
||||||
itemRendererService,
|
itemRendererService,
|
||||||
commandController,
|
commandController,
|
||||||
scriptController,
|
//scriptController,
|
||||||
eventBus,
|
eventBus,
|
||||||
keyBindingController,
|
keyBindingController,
|
||||||
pasteboardProvider,
|
pasteboardProvider,
|
||||||
|
@ -196,8 +199,13 @@ func main() {
|
||||||
p := tea.NewProgram(model, tea.WithAltScreen())
|
p := tea.NewProgram(model, tea.WithAltScreen())
|
||||||
|
|
||||||
jobsController.SetMessageSender(p.Send)
|
jobsController.SetMessageSender(p.Send)
|
||||||
scriptController.Init()
|
//scriptController.Init()
|
||||||
scriptController.SetMessageSender(p.Send)
|
//scriptController.SetMessageSender(p.Send)
|
||||||
|
|
||||||
|
if err := commandController.LoadExtensions(context.Background(), strings.Split(*flagExtDir, string(os.PathListSeparator))); err != nil {
|
||||||
|
fmt.Printf("Unable to load extensions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
go commandController.StartMessageSender(p.Send)
|
go commandController.StartMessageSender(p.Send)
|
||||||
|
|
||||||
log.Println("launching")
|
log.Println("launching")
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -117,5 +117,5 @@ require (
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
ucl.lmika.dev v0.0.0-20250519120409-53b05b5ba6f8 // indirect
|
ucl.lmika.dev v0.0.0-20250525023717-3076897eb73e // indirect
|
||||||
)
|
)
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -460,3 +460,5 @@ ucl.lmika.dev v0.0.0-20250519114239-7ca821016e9a h1:dzBBFCY50+MQcJaQ90swdDyjzag5
|
||||||
ucl.lmika.dev v0.0.0-20250519114239-7ca821016e9a/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
ucl.lmika.dev v0.0.0-20250519114239-7ca821016e9a/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
||||||
ucl.lmika.dev v0.0.0-20250519120409-53b05b5ba6f8 h1:h32JQi0d1MI86RaAMaEU7kvti4uSLX5XYe/nk2abApg=
|
ucl.lmika.dev v0.0.0-20250519120409-53b05b5ba6f8 h1:h32JQi0d1MI86RaAMaEU7kvti4uSLX5XYe/nk2abApg=
|
||||||
ucl.lmika.dev v0.0.0-20250519120409-53b05b5ba6f8/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
ucl.lmika.dev v0.0.0-20250519120409-53b05b5ba6f8/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
||||||
|
ucl.lmika.dev v0.0.0-20250525023717-3076897eb73e h1:N+HzQUunDUvdjAzbSDtHQZVZ1k+XHbVgbNwmc+EKmlQ=
|
||||||
|
ucl.lmika.dev v0.0.0-20250525023717-3076897eb73e/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
||||||
|
|
46
internal/common/ui/commandctrl/cmdpacks/modpb.go
Normal file
46
internal/common/ui/commandctrl/cmdpacks/modpb.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package cmdpacks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/pasteboardprovider"
|
||||||
|
"ucl.lmika.dev/ucl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pbModule struct {
|
||||||
|
pasteboardProvider *pasteboardprovider.Provider
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m pbModule) pbGet(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
|
s, ok := m.pasteboardProvider.ReadText()
|
||||||
|
if !ok {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m pbModule) pbPut(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
|
var s string
|
||||||
|
if err := args.Bind(&s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := m.pasteboardProvider.WriteText([]byte(s)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func modulePB(
|
||||||
|
pasteboardProvider *pasteboardprovider.Provider,
|
||||||
|
) ucl.Module {
|
||||||
|
m := &pbModule{
|
||||||
|
pasteboardProvider: pasteboardProvider,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ucl.Module{
|
||||||
|
Name: "pb",
|
||||||
|
Builtins: map[string]ucl.BuiltinHandler{
|
||||||
|
"get": m.pbGet,
|
||||||
|
"put": m.pbPut,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -252,13 +252,36 @@ func (rs *rsModule) rsSet(ctx context.Context, args ucl.CallArgs) (_ any, err er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEMP
|
// TEMP: attribute is always S
|
||||||
if err := q.SetEvalItem(item.item, &types.AttributeValueMemberS{Value: val.String()}); err != nil {
|
if err := q.SetEvalItem(item.item, &types.AttributeValueMemberS{Value: val.String()}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
item.resultSet.SetDirty(item.idx, true)
|
item.resultSet.SetDirty(item.idx, true)
|
||||||
commandctrl.QueueRefresh(ctx)
|
commandctrl.QueueRefresh(ctx)
|
||||||
// END TEMP
|
|
||||||
|
return item, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs *rsModule) rsDel(ctx context.Context, args ucl.CallArgs) (_ any, err error) {
|
||||||
|
var (
|
||||||
|
item itemProxy
|
||||||
|
expr string
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := args.Bind(&item, &expr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
q, err := queryexpr.Parse(expr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.DeleteAttribute(item.item); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
item.resultSet.SetDirty(item.idx, true)
|
||||||
|
commandctrl.QueueRefresh(ctx)
|
||||||
|
|
||||||
return item, nil
|
return item, nil
|
||||||
}
|
}
|
||||||
|
@ -279,6 +302,7 @@ func moduleRS(tableService *tables.Service, state *controllers.State) ucl.Module
|
||||||
"next-page": m.rsNextPage,
|
"next-page": m.rsNextPage,
|
||||||
"union": m.rsUnion,
|
"union": m.rsUnion,
|
||||||
"set": m.rsSet,
|
"set": m.rsSet,
|
||||||
|
"del": m.rsDel,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,20 @@ type uiModule struct {
|
||||||
readController *controllers.TableReadController
|
readController *controllers.TableReadController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *uiModule) uiCommand(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
|
var (
|
||||||
|
name string
|
||||||
|
cmd ucl.Invokable
|
||||||
|
)
|
||||||
|
if err := args.Bind(&name, &cmd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
invoker := commandctrl.GetInvoker(ctx)
|
||||||
|
invoker.Inst().SetBuiltinInvokable(name, cmd)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *uiModule) uiPrompt(ctx context.Context, args ucl.CallArgs) (any, error) {
|
func (m *uiModule) uiPrompt(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||||
var prompt string
|
var prompt string
|
||||||
if err := args.Bind(&prompt); err != nil {
|
if err := args.Bind(&prompt); err != nil {
|
||||||
|
@ -152,6 +166,7 @@ func moduleUI(
|
||||||
return ucl.Module{
|
return ucl.Module{
|
||||||
Name: "ui",
|
Name: "ui",
|
||||||
Builtins: map[string]ucl.BuiltinHandler{
|
Builtins: map[string]ucl.BuiltinHandler{
|
||||||
|
"command": m.uiCommand,
|
||||||
"prompt": m.uiPrompt,
|
"prompt": m.uiPrompt,
|
||||||
"prompt-table": m.uiPromptTable,
|
"prompt-table": m.uiPromptTable,
|
||||||
"confirm": m.uiConfirm,
|
"confirm": m.uiConfirm,
|
||||||
|
|
|
@ -126,8 +126,8 @@ var keyAttributeProxyFields = &proxyInfo[models.KeyAttribute]{
|
||||||
return fmt.Sprintf("KeyAttribute(%v,%v)", t.PartitionKey, t.SortKey)
|
return fmt.Sprintf("KeyAttribute(%v,%v)", t.PartitionKey, t.SortKey)
|
||||||
},
|
},
|
||||||
fields: map[string]func(t models.KeyAttribute) ucl.Object{
|
fields: map[string]func(t models.KeyAttribute) ucl.Object{
|
||||||
"PartitionKey": func(t models.KeyAttribute) ucl.Object { return ucl.StringObject(t.PartitionKey) },
|
"PK": func(t models.KeyAttribute) ucl.Object { return ucl.StringObject(t.PartitionKey) },
|
||||||
"SortKey": func(t models.KeyAttribute) ucl.Object { return ucl.StringObject(t.SortKey) },
|
"SK": func(t models.KeyAttribute) ucl.Object { return ucl.StringObject(t.SortKey) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl"
|
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl"
|
||||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
|
||||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/models"
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/models"
|
||||||
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/pasteboardprovider"
|
||||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables"
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"ucl.lmika.dev/repl"
|
"ucl.lmika.dev/repl"
|
||||||
|
@ -19,6 +20,7 @@ type StandardCommands struct {
|
||||||
WriteController *controllers.TableWriteController
|
WriteController *controllers.TableWriteController
|
||||||
ExportController *controllers.ExportController
|
ExportController *controllers.ExportController
|
||||||
KeyBindingController *controllers.KeyBindingController
|
KeyBindingController *controllers.KeyBindingController
|
||||||
|
PBProvider *pasteboardprovider.Provider
|
||||||
|
|
||||||
modUI ucl.Module
|
modUI ucl.Module
|
||||||
}
|
}
|
||||||
|
@ -30,6 +32,7 @@ func NewStandardCommands(
|
||||||
writeController *controllers.TableWriteController,
|
writeController *controllers.TableWriteController,
|
||||||
exportController *controllers.ExportController,
|
exportController *controllers.ExportController,
|
||||||
keyBindingController *controllers.KeyBindingController,
|
keyBindingController *controllers.KeyBindingController,
|
||||||
|
pbProvider *pasteboardprovider.Provider,
|
||||||
) StandardCommands {
|
) StandardCommands {
|
||||||
modUI, ckbs := moduleUI(tableService, state, readController)
|
modUI, ckbs := moduleUI(tableService, state, readController)
|
||||||
keyBindingController.SetCustomKeyBindingSource(ckbs)
|
keyBindingController.SetCustomKeyBindingSource(ckbs)
|
||||||
|
@ -41,6 +44,7 @@ func NewStandardCommands(
|
||||||
WriteController: writeController,
|
WriteController: writeController,
|
||||||
ExportController: exportController,
|
ExportController: exportController,
|
||||||
KeyBindingController: keyBindingController,
|
KeyBindingController: keyBindingController,
|
||||||
|
PBProvider: pbProvider,
|
||||||
modUI: modUI,
|
modUI: modUI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,6 +393,7 @@ func (sc StandardCommands) InstOptions() []ucl.InstOption {
|
||||||
return []ucl.InstOption{
|
return []ucl.InstOption{
|
||||||
ucl.WithModule(moduleRS(sc.TableService, sc.State)),
|
ucl.WithModule(moduleRS(sc.TableService, sc.State)),
|
||||||
ucl.WithModule(sc.modUI),
|
ucl.WithModule(sc.modUI),
|
||||||
|
ucl.WithModule(modulePB(sc.PBProvider)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package commandctrl
|
package commandctrl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
@ -136,7 +137,7 @@ func (c *CommandController) execute(ctx ExecContext, commandInput string) tea.Ms
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandController) ExecuteAndWait(ctx context.Context, commandInput string) (any, error) {
|
func (c *CommandController) ExecuteAndWait(ctx context.Context, commandInput string) (any, error) {
|
||||||
return c.uclInst.Eval(ctx, commandInput)
|
return c.uclInst.EvalString(ctx, commandInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandController) Invoke(invokable ucl.Invokable, args []any) (msg tea.Msg) {
|
func (c *CommandController) Invoke(invokable ucl.Invokable, args []any) (msg tea.Msg) {
|
||||||
|
@ -202,7 +203,47 @@ func (c *CommandController) lookupCommand(name string) Command {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandController) ExecuteFile(filename string) error {
|
func (c *CommandController) LoadExtensions(ctx context.Context, baseDirs []string) error {
|
||||||
|
log.Printf("loading extensions: %v", baseDirs)
|
||||||
|
for _, baseDir := range baseDirs {
|
||||||
|
baseDir = os.ExpandEnv(baseDir)
|
||||||
|
descendIntoSubDirs := !strings.HasSuffix(baseDir, ".")
|
||||||
|
|
||||||
|
if stat, err := os.Stat(baseDir); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
} else if !stat.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("walking %v", baseDir)
|
||||||
|
if err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
if !descendIntoSubDirs && path != baseDir {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(info.Name(), ".ucl") {
|
||||||
|
if err := c.ExecuteFile(ctx, path); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
log.Printf("loaded %v\n", path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandController) ExecuteFile(ctx context.Context, filename string) error {
|
||||||
oldInteractive := c.interactive
|
oldInteractive := c.interactive
|
||||||
c.interactive = false
|
c.interactive = false
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -211,27 +252,31 @@ func (c *CommandController) ExecuteFile(filename string) error {
|
||||||
|
|
||||||
baseFilename := filepath.Base(filename)
|
baseFilename := filepath.Base(filename)
|
||||||
|
|
||||||
|
execCtx := execContext{ctrl: c}
|
||||||
|
ctx = context.WithValue(context.Background(), commandCtlKey, &execCtx)
|
||||||
|
|
||||||
if rcFile, err := os.ReadFile(filename); err == nil {
|
if rcFile, err := os.ReadFile(filename); err == nil {
|
||||||
if err := c.executeFile(rcFile, baseFilename); err != nil {
|
if err := c.executeFile(ctx, rcFile); err != nil {
|
||||||
return errors.Wrapf(err, "error executing %v", filename)
|
return errors.Wrapf(err, "error executing %v", baseFilename)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.Wrapf(err, "error loading %v", filename)
|
return errors.Wrapf(err, "error loading %v", baseFilename)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandController) executeFile(file []byte, filename string) error {
|
func (c *CommandController) executeFile(ctx context.Context, file []byte) error {
|
||||||
//msg := c.execute(ExecContext{FromFile: true}, string(file))
|
if _, err := c.uclInst.Eval(ctx, bytes.NewReader(file), ucl.WithSubEnv()); err != nil {
|
||||||
//switch m := msg.(type) {
|
return err
|
||||||
//case events.ErrorMsg:
|
}
|
||||||
// log.Printf("%v: error - %v", filename, m.Error())
|
|
||||||
//case events.StatusMsg:
|
|
||||||
// log.Printf("%v: %v", filename, string(m))
|
|
||||||
//}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CommandController) Inst() *ucl.Inst {
|
||||||
|
return c.uclInst
|
||||||
|
}
|
||||||
|
|
||||||
func (c *CommandController) cmdInvoker(ctx context.Context, name string, args ucl.CallArgs) (any, error) {
|
func (c *CommandController) cmdInvoker(ctx context.Context, name string, args ucl.CallArgs) (any, error) {
|
||||||
command := c.lookupCommand(name)
|
command := c.lookupCommand(name)
|
||||||
if command == nil {
|
if command == nil {
|
||||||
|
|
|
@ -59,4 +59,5 @@ func QueueRefresh(ctx context.Context) {
|
||||||
|
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
Invoke(invokable ucl.Invokable, args []any) tea.Msg
|
Invoke(invokable ucl.Invokable, args []any) tea.Msg
|
||||||
|
Inst() *ucl.Inst
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ func (c *ExportController) ExportCSVToClipboard() tea.Msg {
|
||||||
if err := c.pasteboardProvider.WriteText(bts.Bytes()); err != nil {
|
if err := c.pasteboardProvider.WriteText(bts.Bytes()); err != nil {
|
||||||
return events.Error(err)
|
return events.Error(err)
|
||||||
}
|
}
|
||||||
return nil
|
return events.StatusMsg("Table copied to clipboard")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this really needs to be a service!
|
// TODO: this really needs to be a service!
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/ui/teamodels/utils"
|
"github.com/lmika/dynamo-browse/internal/dynamo-browse/ui/teamodels/utils"
|
||||||
bus "github.com/lmika/events"
|
bus "github.com/lmika/events"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -33,8 +32,6 @@ const (
|
||||||
ViewModeTableOnly = 4
|
ViewModeTableOnly = 4
|
||||||
|
|
||||||
ViewModeCount = 5
|
ViewModeCount = 5
|
||||||
|
|
||||||
initRCFilename = "$HOME/.config/audax/dynamo-browse/init.rc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
|
@ -43,14 +40,14 @@ type Model struct {
|
||||||
settingsController *controllers.SettingsController
|
settingsController *controllers.SettingsController
|
||||||
exportController *controllers.ExportController
|
exportController *controllers.ExportController
|
||||||
commandController *commandctrl.CommandController
|
commandController *commandctrl.CommandController
|
||||||
scriptController *controllers.ScriptController
|
//scriptController *controllers.ScriptController
|
||||||
jobController *controllers.JobsController
|
jobController *controllers.JobsController
|
||||||
colSelector *colselector.Model
|
colSelector *colselector.Model
|
||||||
relSelector *relselector.Model
|
relSelector *relselector.Model
|
||||||
itemEdit *dynamoitemedit.Model
|
itemEdit *dynamoitemedit.Model
|
||||||
statusAndPrompt *statusandprompt.StatusAndPrompt
|
statusAndPrompt *statusandprompt.StatusAndPrompt
|
||||||
tableSelect *tableselect.Model
|
tableSelect *tableselect.Model
|
||||||
eventBus *bus.Bus
|
eventBus *bus.Bus
|
||||||
|
|
||||||
mainViewIndex int
|
mainViewIndex int
|
||||||
|
|
||||||
|
@ -71,7 +68,7 @@ func NewModel(
|
||||||
jobController *controllers.JobsController,
|
jobController *controllers.JobsController,
|
||||||
itemRendererService *itemrenderer.Service,
|
itemRendererService *itemrenderer.Service,
|
||||||
cc *commandctrl.CommandController,
|
cc *commandctrl.CommandController,
|
||||||
scriptController *controllers.ScriptController,
|
//scriptController *controllers.ScriptController,
|
||||||
eventBus *bus.Bus,
|
eventBus *bus.Bus,
|
||||||
keyBindingController *controllers.KeyBindingController,
|
keyBindingController *controllers.KeyBindingController,
|
||||||
pasteboardProvider services.PasteboardProvider,
|
pasteboardProvider services.PasteboardProvider,
|
||||||
|
@ -255,7 +252,8 @@ func NewModel(
|
||||||
tableReadController: rc,
|
tableReadController: rc,
|
||||||
tableWriteController: wc,
|
tableWriteController: wc,
|
||||||
commandController: cc,
|
commandController: cc,
|
||||||
scriptController: scriptController,
|
//scriptController: scriptController,
|
||||||
|
exportController: exportController,
|
||||||
jobController: jobController,
|
jobController: jobController,
|
||||||
itemEdit: itemEdit,
|
itemEdit: itemEdit,
|
||||||
colSelector: colSelector,
|
colSelector: colSelector,
|
||||||
|
@ -318,10 +316,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
// return m, nil
|
// return m, nil
|
||||||
case key.Matches(msg, m.keyMap.ShowColumnOverlay):
|
case key.Matches(msg, m.keyMap.ShowColumnOverlay):
|
||||||
return m, events.SetTeaMessage(controllers.ShowColumnOverlay{})
|
return m, events.SetTeaMessage(controllers.ShowColumnOverlay{})
|
||||||
case key.Matches(msg, m.keyMap.ShowRelItemsOverlay):
|
//case key.Matches(msg, m.keyMap.ShowRelItemsOverlay):
|
||||||
if idx := m.tableView.SelectedItemIndex(); idx >= 0 {
|
// if idx := m.tableView.SelectedItemIndex(); idx >= 0 {
|
||||||
return m, events.SetTeaMessage(m.scriptController.LookupRelatedItems(idx))
|
// return m, events.SetTeaMessage(m.scriptController.LookupRelatedItems(idx))
|
||||||
}
|
// }
|
||||||
case key.Matches(msg, m.keyMap.PromptForCommand):
|
case key.Matches(msg, m.keyMap.PromptForCommand):
|
||||||
return m, m.commandController.Prompt
|
return m, m.commandController.Prompt
|
||||||
case key.Matches(msg, m.keyMap.PromptForTable):
|
case key.Matches(msg, m.keyMap.PromptForTable):
|
||||||
|
@ -344,12 +342,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) Init() tea.Cmd {
|
func (m Model) Init() tea.Cmd {
|
||||||
// TODO: this should probably be moved somewhere else
|
|
||||||
rcFilename := os.ExpandEnv(initRCFilename)
|
|
||||||
if err := m.commandController.ExecuteFile(rcFilename); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tea.Batch(
|
return tea.Batch(
|
||||||
m.tableReadController.Init,
|
m.tableReadController.Init,
|
||||||
m.root.Init(),
|
m.root.Init(),
|
||||||
|
|
Loading…
Reference in a new issue