Added command history (#45)

* Added command line history to the command, query and filter prompts.
* Added query planning debugging to the log.
* Fixed bug in query expression which was not treating true and false as boolean literals.
* Fixed a bug in the query planning logic which was incorrectly determine that an expression of the form sort_key ^= "string", with no partition key, could be executed as a query instead of a scan.
This commit is contained in:
Leon Mika 2023-01-26 21:46:31 +11:00 committed by GitHub
parent 700a1a2253
commit 54a120342e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 335 additions and 34 deletions

View file

@ -3,6 +3,7 @@ package commandctrl
import (
"bufio"
"bytes"
"context"
tea "github.com/charmbracelet/bubbletea"
"github.com/pkg/errors"
"log"
@ -14,13 +15,17 @@ import (
"github.com/lmika/shellwords"
)
const commandsCategory = "commands"
type CommandController struct {
historyProvider IterProvider
commandList *CommandList
lookupExtensions []CommandLookupExtension
}
func NewCommandController() *CommandController {
func NewCommandController(historyProvider IterProvider) *CommandController {
return &CommandController{
historyProvider: historyProvider,
commandList: nil,
lookupExtensions: nil,
}
@ -37,7 +42,8 @@ func (c *CommandController) AddCommandLookupExtension(ext CommandLookupExtension
func (c *CommandController) Prompt() tea.Msg {
return events.PromptForInputMsg{
Prompt: ":",
Prompt: ":",
History: c.historyProvider.Iter(context.Background(), commandsCategory),
OnDone: func(value string) tea.Msg {
return c.Execute(value)
},

View file

@ -1,7 +1,9 @@
package commandctrl_test
import (
"context"
"github.com/lmika/audax/internal/common/ui/events"
"github.com/lmika/audax/internal/dynamo-browse/services"
"testing"
"github.com/lmika/audax/internal/common/ui/commandctrl"
@ -10,7 +12,7 @@ import (
func TestCommandController_Prompt(t *testing.T) {
t.Run("prompt user for a command", func(t *testing.T) {
cmd := commandctrl.NewCommandController()
cmd := commandctrl.NewCommandController(mockIterProvider{})
res := cmd.Prompt()
@ -19,3 +21,10 @@ func TestCommandController_Prompt(t *testing.T) {
assert.Equal(t, ":", promptForInputMsg.Prompt)
})
}
type mockIterProvider struct {
}
func (m mockIterProvider) Iter(ctx context.Context, category string) services.HistoryProvider {
return nil
}

View file

@ -0,0 +1,10 @@
package commandctrl
import (
"context"
"github.com/lmika/audax/internal/dynamo-browse/services"
)
type IterProvider interface {
Iter(ctx context.Context, category string) services.HistoryProvider
}

View file

@ -2,6 +2,7 @@ package events
import (
tea "github.com/charmbracelet/bubbletea"
"github.com/lmika/audax/internal/dynamo-browse/services"
"log"
)
@ -22,21 +23,22 @@ func SetTeaMessage(event tea.Msg) tea.Cmd {
}
}
func PromptForInput(prompt string, onDone func(value string) tea.Msg) tea.Msg {
func PromptForInput(prompt string, history services.HistoryProvider, onDone func(value string) tea.Msg) tea.Msg {
return PromptForInputMsg{
Prompt: prompt,
OnDone: onDone,
Prompt: prompt,
History: history,
OnDone: onDone,
}
}
func Confirm(prompt string, onResult func(yes bool) tea.Msg) tea.Msg {
return PromptForInput(prompt, func(value string) tea.Msg {
return PromptForInput(prompt, nil, func(value string) tea.Msg {
return onResult(value == "y")
})
}
func ConfirmYes(prompt string, onYes func() tea.Msg) tea.Msg {
return PromptForInput(prompt, func(value string) tea.Msg {
return PromptForInput(prompt, nil, func(value string) tea.Msg {
if value == "y" {
return onYes()
}

View file

@ -2,6 +2,7 @@ package events
import (
tea "github.com/charmbracelet/bubbletea"
"github.com/lmika/audax/internal/dynamo-browse/services"
)
// Error indicates that an error occurred
@ -21,6 +22,7 @@ type ModeMessage string
// PromptForInput indicates that the context is requesting a line of input
type PromptForInputMsg struct {
Prompt string
History services.HistoryProvider
OnDone func(value string) tea.Msg
OnCancel func() tea.Msg
}