From f2358a1ab538aa21d4ff8fe3fa6e22b46d5e1c39 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sat, 12 Jul 2025 22:25:09 -0700 Subject: [PATCH] remove q to quit --- edit_cell.go | 32 ++++++++++++++++---------------- main.go | 6 +++--- query.go | 19 ++++++++++++++++++- row_detail.go | 3 +-- table_data.go | 3 +-- table_list.go | 16 ++++++++-------- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/edit_cell.go b/edit_cell.go index b6fbaf3..13ba676 100644 --- a/edit_cell.go +++ b/edit_cell.go @@ -22,7 +22,7 @@ func newEditCellModel(shared *sharedData, rowIndex, colIndex int) *editCellModel if rowIndex < len(shared.filteredData) && colIndex < len(shared.filteredData[rowIndex]) { originalValue = shared.filteredData[rowIndex][colIndex] } - + return &editCellModel{ shared: shared, rowIndex: rowIndex, @@ -126,17 +126,17 @@ func (m *editCellModel) wordLeft(pos int) int { if pos == 0 { return 0 } - + // Skip whitespace for pos > 0 && isWhitespace(m.editingValue[pos-1]) { pos-- } - + // Skip non-whitespace for pos > 0 && !isWhitespace(m.editingValue[pos-1]) { pos-- } - + return pos } @@ -145,17 +145,17 @@ func (m *editCellModel) wordRight(pos int) int { if pos >= length { return length } - + // Skip non-whitespace for pos < length && !isWhitespace(m.editingValue[pos]) { pos++ } - + // Skip whitespace for pos < length && isWhitespace(m.editingValue[pos]) { pos++ } - + return pos } @@ -167,13 +167,13 @@ func (m *editCellModel) View() string { if m.colIndex < len(m.shared.columns) { columnName = m.shared.columns[m.colIndex] } - + content.WriteString(titleStyle.Render(fmt.Sprintf("Edit: %s.%s", tableName, columnName))) content.WriteString("\n\n") - + // Calculate available width for text (leave some margin) textWidth := max(20, m.shared.width-4) - + // Wrap original value content.WriteString("Original:") content.WriteString("\n") @@ -182,13 +182,13 @@ func (m *editCellModel) View() string { content.WriteString(" " + line) content.WriteString("\n") } - + content.WriteString("\n") - + // Wrap new value with cursor content.WriteString("New:") content.WriteString("\n") - + // Display editing value with cursor valueWithCursor := "" if m.cursorPos <= len(m.editingValue) { @@ -198,15 +198,15 @@ func (m *editCellModel) View() string { } else { valueWithCursor = m.editingValue + "█" } - + newLines := wrapText(valueWithCursor, textWidth) for _, line := range newLines { content.WriteString(" " + line) content.WriteString("\n") } - + content.WriteString("\n") content.WriteString(helpStyle.Render("←/→: move cursor • ctrl+←/→: word nav • home/end: line nav • ctrl+w/k/u: delete • enter: save • esc: cancel")) return content.String() -} \ No newline at end of file +} diff --git a/main.go b/main.go index 3119fd5..1feca38 100644 --- a/main.go +++ b/main.go @@ -498,7 +498,7 @@ func max(a, b int) int { } func initialModel(dbPath string) model { - db, err := sql.Open("sqlite3", dbPath) + db, err := sql.Open("sqlite", dbPath) if err != nil { return model{err: err} } @@ -533,7 +533,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Add similar updates for other model types as needed case tea.KeyMsg: - if msg.String() == "ctrl+c" || msg.String() == "q" { + if msg.String() == "ctrl+c" { return m, tea.Quit } @@ -606,7 +606,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m model) View() string { if m.err != nil { - return errorStyle.Render(fmt.Sprintf("Error: %v\n\nPress 'q' to quit", m.err)) + return errorStyle.Render(fmt.Sprintf("Error: %v\n\nPress 'ctrl+c' to quit", m.err)) } return m.currentView.View() } diff --git a/query.go b/query.go index 518b041..baa4643 100644 --- a/query.go +++ b/query.go @@ -17,6 +17,7 @@ type queryModel struct { columns []string focusOnInput bool // true = input focused, false = results focused selectedRow int + errorMsg string // Error message to display } func newQueryModel(shared *sharedData) *queryModel { @@ -42,6 +43,11 @@ func (m *queryModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *queryModel) handleInput(msg tea.KeyMsg) (tea.Model, tea.Cmd) { switch msg.String() { case "esc": + // Clear error message if present, otherwise go back + if m.errorMsg != "" { + m.errorMsg = "" + return m, nil + } return m, func() tea.Msg { return switchToTableListMsg{} } case "tab": @@ -59,7 +65,9 @@ func (m *queryModel) handleInput(msg tea.KeyMsg) (tea.Model, tea.Cmd) { if m.focusOnInput { // Execute query when input is focused if err := m.executeQuery(); err != nil { - // TODO: Handle error - could set an error field + m.errorMsg = err.Error() + } else { + m.errorMsg = "" // Clear error on successful query } } else { // View row detail when results are focused @@ -281,6 +289,15 @@ func (m *queryModel) View() string { content.WriteString(titleStyle.Render("SQL Query")) content.WriteString("\n\n") + // Display error modal if there's an error + if m.errorMsg != "" { + errorBox := errorStyle.Render(fmt.Sprintf("Error: %s", m.errorMsg)) + content.WriteString(errorBox) + content.WriteString("\n\n") + content.WriteString(helpStyle.Render("esc: dismiss error")) + return content.String() + } + // Display query with cursor and focus indicator if m.focusOnInput { content.WriteString("Query: ") diff --git a/row_detail.go b/row_detail.go index 13e6250..1a3213e 100644 --- a/row_detail.go +++ b/row_detail.go @@ -166,8 +166,7 @@ func (m *rowDetailModel) View() string { } content.WriteString("\n") - content.WriteString(helpStyle.Render("↑/↓: select field • enter: edit • esc: back • q: quit")) + content.WriteString(helpStyle.Render("↑/↓: select field • enter: edit • esc: back • ctrl+c: quit")) return content.String() } - diff --git a/table_data.go b/table_data.go index 838b9d9..e0471e4 100644 --- a/table_data.go +++ b/table_data.go @@ -221,9 +221,8 @@ func (m *tableDataModel) View() string { if m.searching { content.WriteString(helpStyle.Render("Type to search • enter/esc: finish search")) } else { - content.WriteString(helpStyle.Render("↑/↓: select row • ←/→: page • /: search • enter: view row • esc: back • r: refresh • q: quit")) + content.WriteString(helpStyle.Render("↑/↓: select row • ←/→: page • /: search • enter: view row • esc: back • r: refresh • ctrl+c: quit")) } return content.String() } - diff --git a/table_list.go b/table_list.go index a175c38..50b6059 100644 --- a/table_list.go +++ b/table_list.go @@ -124,7 +124,7 @@ func (m *tableListModel) filterTables() { } } } - + if m.selectedTable >= len(m.shared.filteredTables) { m.selectedTable = 0 m.currentPage = 0 @@ -149,12 +149,12 @@ func (m *tableListModel) View() string { content.WriteString(titleStyle.Render("SQLite TUI - Tables")) content.WriteString("\n") - + if m.searching { content.WriteString("\nSearch: " + m.searchInput + "_") content.WriteString("\n") } else if m.searchInput != "" { - content.WriteString(fmt.Sprintf("\nFiltered by: %s (%d/%d tables)", + content.WriteString(fmt.Sprintf("\nFiltered by: %s (%d/%d tables)", m.searchInput, len(m.shared.filteredTables), len(m.shared.tables))) content.WriteString("\n") } @@ -170,7 +170,7 @@ func (m *tableListModel) View() string { visibleCount := m.getVisibleCount() startIdx := m.currentPage * visibleCount endIdx := min(startIdx+visibleCount, len(m.shared.filteredTables)) - + for i := startIdx; i < endIdx; i++ { table := m.shared.filteredTables[i] if i == m.selectedTable { @@ -180,9 +180,9 @@ func (m *tableListModel) View() string { } content.WriteString("\n") } - + if len(m.shared.filteredTables) > visibleCount { - totalPages := (len(m.shared.filteredTables) - 1) / visibleCount + 1 + totalPages := (len(m.shared.filteredTables)-1)/visibleCount + 1 content.WriteString(fmt.Sprintf("\nPage %d/%d", m.currentPage+1, totalPages)) } } @@ -191,8 +191,8 @@ func (m *tableListModel) View() string { if m.searching { content.WriteString(helpStyle.Render("Type to search • enter/esc: finish search")) } else { - content.WriteString(helpStyle.Render("↑/↓: navigate • ←/→: page • /: search • enter: view • s: SQL • r: refresh • q: quit")) + content.WriteString(helpStyle.Render("↑/↓: navigate • ←/→: page • /: search • enter: view • s: SQL • r: refresh • ctrl+c: quit")) } return content.String() -} \ No newline at end of file +}