mirror of
https://github.com/ddworken/hishtory.git
synced 2025-06-26 15:02:00 +02:00
Persist history entries in the TUI model to prep for #33
This commit is contained in:
parent
16d8755c01
commit
554d518caa
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/charmbracelet/bubbles/textinput"
|
"github.com/charmbracelet/bubbles/textinput"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/ddworken/hishtory/client/data"
|
||||||
"github.com/ddworken/hishtory/client/hctx"
|
"github.com/ddworken/hishtory/client/hctx"
|
||||||
"github.com/muesli/termenv"
|
"github.com/muesli/termenv"
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
@ -42,8 +43,8 @@ type model struct {
|
|||||||
|
|
||||||
// The table used for displaying search results.
|
// The table used for displaying search results.
|
||||||
table table.Model
|
table table.Model
|
||||||
// The number of entries in the table.
|
// The entries in the table
|
||||||
numEntries int
|
tableEntries []*data.HistoryEntry
|
||||||
// Whether the user has hit enter to select an entry and the TUI is thus about to quit.
|
// Whether the user has hit enter to select an entry and the TUI is thus about to quit.
|
||||||
selected bool
|
selected bool
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ type bannerMsg struct {
|
|||||||
banner string
|
banner string
|
||||||
}
|
}
|
||||||
|
|
||||||
func initialModel(ctx *context.Context, t table.Model, initialQuery string, numEntries int) model {
|
func initialModel(ctx *context.Context, t table.Model, tableEntries []*data.HistoryEntry, initialQuery string) model {
|
||||||
s := spinner.New()
|
s := spinner.New()
|
||||||
s.Spinner = spinner.Dot
|
s.Spinner = spinner.Dot
|
||||||
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
|
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
|
||||||
@ -83,7 +84,7 @@ func initialModel(ctx *context.Context, t table.Model, initialQuery string, numE
|
|||||||
if initialQuery != "" {
|
if initialQuery != "" {
|
||||||
queryInput.SetValue(initialQuery)
|
queryInput.SetValue(initialQuery)
|
||||||
}
|
}
|
||||||
return model{ctx: ctx, spinner: s, isLoading: true, table: t, runQuery: &initialQuery, queryInput: queryInput, numEntries: numEntries}
|
return model{ctx: ctx, spinner: s, isLoading: true, table: t, tableEntries: tableEntries, runQuery: &initialQuery, queryInput: queryInput}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m model) Init() tea.Cmd {
|
func (m model) Init() tea.Cmd {
|
||||||
@ -95,12 +96,12 @@ func runQueryAndUpdateTable(m model, updateTable bool) model {
|
|||||||
if m.runQuery == nil {
|
if m.runQuery == nil {
|
||||||
m.runQuery = &m.lastQuery
|
m.runQuery = &m.lastQuery
|
||||||
}
|
}
|
||||||
rows, numEntries, err := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, *m.runQuery, PADDED_NUM_ENTRIES)
|
rows, entries, _, err := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, *m.runQuery, PADDED_NUM_ENTRIES)
|
||||||
m.searchErr = err
|
m.searchErr = err
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
m.numEntries = numEntries
|
m.tableEntries = entries
|
||||||
if updateTable {
|
if updateTable {
|
||||||
t, err := makeTable(m.ctx, rows)
|
t, err := makeTable(m.ctx, rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -114,9 +115,9 @@ func runQueryAndUpdateTable(m model, updateTable bool) model {
|
|||||||
m.lastQuery = *m.runQuery
|
m.lastQuery = *m.runQuery
|
||||||
m.runQuery = nil
|
m.runQuery = nil
|
||||||
}
|
}
|
||||||
if m.table.Cursor() >= m.numEntries {
|
if m.table.Cursor() >= len(m.tableEntries) {
|
||||||
// Ensure that we can't scroll past the end of the table
|
// Ensure that we can't scroll past the end of the table
|
||||||
m.table.SetCursor(m.numEntries - 1)
|
m.table.SetCursor(len(m.tableEntries) - 1)
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.quitting = true
|
m.quitting = true
|
||||||
return m, tea.Quit
|
return m, tea.Quit
|
||||||
case "enter":
|
case "enter":
|
||||||
if m.numEntries != 0 {
|
if len(m.tableEntries) != 0 {
|
||||||
m.selected = true
|
m.selected = true
|
||||||
}
|
}
|
||||||
return m, tea.Quit
|
return m, tea.Quit
|
||||||
@ -206,12 +207,12 @@ func (m model) View() string {
|
|||||||
return fmt.Sprintf("\n%s\n%s%s\nSearch Query: %s\n\n%s\n", loadingMessage, warning, m.banner, m.queryInput.View(), baseStyle.Render(m.table.View()))
|
return fmt.Sprintf("\n%s\n%s%s\nSearch Query: %s\n\n%s\n", loadingMessage, warning, m.banner, m.queryInput.View(), baseStyle.Render(m.table.View()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRows(ctx *context.Context, columnNames []string, query string, numEntries int) ([]table.Row, int, error) {
|
func getRows(ctx *context.Context, columnNames []string, query string, numEntries int) ([]table.Row, []*data.HistoryEntry, int, error) {
|
||||||
db := hctx.GetDb(ctx)
|
db := hctx.GetDb(ctx)
|
||||||
config := hctx.GetConf(ctx)
|
config := hctx.GetConf(ctx)
|
||||||
data, err := Search(ctx, db, query, numEntries)
|
data, err := Search(ctx, db, query, numEntries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, nil, 0, err
|
||||||
}
|
}
|
||||||
var rows []table.Row
|
var rows []table.Row
|
||||||
lastCommand := ""
|
lastCommand := ""
|
||||||
@ -224,7 +225,7 @@ func getRows(ctx *context.Context, columnNames []string, query string, numEntrie
|
|||||||
entry.Command = strings.ReplaceAll(entry.Command, "\n", "\\n")
|
entry.Command = strings.ReplaceAll(entry.Command, "\n", "\\n")
|
||||||
row, err := buildTableRow(ctx, columnNames, *entry)
|
row, err := buildTableRow(ctx, columnNames, *entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("failed to build row for entry=%#v: %v", entry, err)
|
return nil, nil, 0, fmt.Errorf("failed to build row for entry=%#v: %v", entry, err)
|
||||||
}
|
}
|
||||||
rows = append(rows, row)
|
rows = append(rows, row)
|
||||||
lastCommand = entry.Command
|
lastCommand = entry.Command
|
||||||
@ -232,7 +233,7 @@ func getRows(ctx *context.Context, columnNames []string, query string, numEntrie
|
|||||||
rows = append(rows, table.Row{})
|
rows = append(rows, table.Row{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rows, len(data), nil
|
return rows, data, len(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateColumnWidths(rows []table.Row, numColumns int) []int {
|
func calculateColumnWidths(rows []table.Row, numColumns int) []int {
|
||||||
@ -254,7 +255,7 @@ var bigQueryResults []table.Row
|
|||||||
func makeTableColumns(ctx *context.Context, columnNames []string, rows []table.Row) ([]table.Column, error) {
|
func makeTableColumns(ctx *context.Context, columnNames []string, rows []table.Row) ([]table.Column, error) {
|
||||||
// Handle an initial query with no results
|
// Handle an initial query with no results
|
||||||
if len(rows) == 0 || len(rows[0]) == 0 {
|
if len(rows) == 0 || len(rows[0]) == 0 {
|
||||||
allRows, _, err := getRows(ctx, columnNames, "", 25)
|
allRows, _, _, err := getRows(ctx, columnNames, "", 25)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -280,7 +281,7 @@ func makeTableColumns(ctx *context.Context, columnNames []string, rows []table.R
|
|||||||
|
|
||||||
// Calculate the maximum column width that is useful for each column if we search for the empty string
|
// Calculate the maximum column width that is useful for each column if we search for the empty string
|
||||||
if bigQueryResults == nil {
|
if bigQueryResults == nil {
|
||||||
bigRows, _, err := getRows(ctx, columnNames, "", 1000)
|
bigRows, _, _, err := getRows(ctx, columnNames, "", 1000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -403,7 +404,7 @@ func makeTable(ctx *context.Context, rows []table.Row) (table.Model, error) {
|
|||||||
|
|
||||||
func TuiQuery(ctx *context.Context, initialQuery string) error {
|
func TuiQuery(ctx *context.Context, initialQuery string) error {
|
||||||
lipgloss.SetColorProfile(termenv.ANSI)
|
lipgloss.SetColorProfile(termenv.ANSI)
|
||||||
rows, numEntries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, initialQuery, PADDED_NUM_ENTRIES)
|
rows, entries, _, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, initialQuery, PADDED_NUM_ENTRIES)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if initialQuery != "" {
|
if initialQuery != "" {
|
||||||
// initialQuery is likely invalid in some way, let's just drop it
|
// initialQuery is likely invalid in some way, let's just drop it
|
||||||
@ -416,7 +417,7 @@ func TuiQuery(ctx *context.Context, initialQuery string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p := tea.NewProgram(initialModel(ctx, t, initialQuery, numEntries), tea.WithOutput(os.Stderr))
|
p := tea.NewProgram(initialModel(ctx, t, entries, initialQuery), tea.WithOutput(os.Stderr))
|
||||||
// Async: Retrieve additional entries from the backend
|
// Async: Retrieve additional entries from the backend
|
||||||
go func() {
|
go func() {
|
||||||
err := RetrieveAdditionalEntriesFromRemote(ctx)
|
err := RetrieveAdditionalEntriesFromRemote(ctx)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user