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:
parent
700a1a2253
commit
54a120342e
26 changed files with 335 additions and 34 deletions
|
|
@ -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)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
10
internal/common/ui/commandctrl/iface.go
Normal file
10
internal/common/ui/commandctrl/iface.go
Normal 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
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue