jerry-rig a help toggle cmd

This commit is contained in:
2025-07-13 20:56:16 -07:00
parent 96b10e7b00
commit 5543a9a8e0
10 changed files with 147 additions and 55 deletions

View File

@@ -28,8 +28,9 @@ type blinkMsg struct{}
// AppKeyMap defines the keybindings for the application
type AppKeyMap struct {
Quit key.Binding
Suspend key.Binding
Quit key.Binding
Suspend key.Binding
ToggleHelp key.Binding
}
// DefaultAppKeyMap returns the default keybindings
@@ -43,6 +44,10 @@ func DefaultAppKeyMap() AppKeyMap {
key.WithKeys("ctrl+z"),
key.WithHelp("ctrl+z", "suspend"),
),
ToggleHelp: key.NewBinding(
key.WithKeys("ctrl+g"),
key.WithHelp("ctrl+g", "toggle help"),
),
}
}
@@ -57,6 +62,7 @@ type (
SwitchToQueryMsg struct{}
ReturnToQueryMsg struct{} // Return to query mode from row detail
RefreshDataMsg struct{}
ToggleHelpMsg struct{} // Toggle between short and full help
UpdateCellMsg struct {
RowIndex, ColIndex int
Value string
@@ -594,6 +600,8 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit
case key.Matches(msg, m.keyMap.Suspend):
return m, tea.Suspend
case key.Matches(msg, m.keyMap.ToggleHelp):
return m, func() tea.Msg { return ToggleHelpMsg{} }
}
case SwitchToTableListMsg:
@@ -667,6 +675,12 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
queryModel.handleQueryCompletion(msg)
}
return m, nil
case ToggleHelpMsg:
// Forward the help toggle to the current view
var cmd tea.Cmd
m.currentView, cmd = m.currentView.Update(msg)
return m, cmd
}
if m.err != nil {

View File

@@ -11,15 +11,16 @@ import (
)
type EditCellModel struct {
Shared *SharedData
rowIndex int
colIndex int
input textinput.Model
blinkState bool
keyMap EditCellKeyMap
help help.Model
focused bool
id int
Shared *SharedData
rowIndex int
colIndex int
input textinput.Model
blinkState bool
keyMap EditCellKeyMap
help help.Model
showFullHelp bool
focused bool
id int
}
// EditCellOption is a functional option for configuring EditCellModel
@@ -106,6 +107,10 @@ func (m *EditCellModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case ToggleHelpMsg:
m.showFullHelp = !m.showFullHelp
return m, nil
case blinkMsg:
m.blinkState = !m.blinkState
cmds = append(cmds, blinkCmd())
@@ -146,7 +151,16 @@ func (m *EditCellModel) View() string {
content := fmt.Sprintf("%s\n\n", TitleStyle.Render(fmt.Sprintf("Edit Cell: %s", columnName)))
content += fmt.Sprintf("Value: %s\n\n", m.input.View())
content += m.help.View(m.keyMap)
var helpText string
if m.showFullHelp {
helpText = m.help.FullHelpView(m.keyMap.FullHelp())
} else {
helpText = m.help.ShortHelpView(m.keyMap.ShortHelp())
// Add ctrl+g to short help
helpText += " • " + HelpStyle.Render("ctrl+g: toggle help")
}
content += helpText
return content
}

View File

@@ -23,6 +23,7 @@ type QueryModel struct {
gPressed bool
keyMap QueryKeyMap
help help.Model
showFullHelp bool
focused bool
id int
}
@@ -105,6 +106,10 @@ func (m *QueryModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case ToggleHelpMsg:
m.showFullHelp = !m.showFullHelp
return m, nil
case blinkMsg:
m.blinkState = !m.blinkState
cmds = append(cmds, tea.Tick(time.Millisecond*500, func(t time.Time) tea.Msg {
@@ -156,17 +161,17 @@ func (m *QueryModel) handleResultsNavigation(msg tea.KeyMsg) (tea.Model, tea.Cmd
case key.Matches(msg, m.keyMap.GoToStart):
if m.gPressed {
// Second g - go to beginning
// Second g - go to beginning (gg pattern like vim)
m.selectedRow = 0
m.gPressed = false
} else {
// First g - wait for second g
// First g - wait for second g to complete gg sequence
m.gPressed = true
}
return m, nil
case key.Matches(msg, m.keyMap.GoToEnd):
// Go to end
// Go to end (G pattern like vim)
if len(m.results) > 0 {
m.selectedRow = len(m.results) - 1
}
@@ -449,9 +454,17 @@ func (m *QueryModel) View() string {
content.WriteString("\n")
if m.FocusOnInput {
content.WriteString(HelpStyle.Render("enter: execute • esc: back"))
content.WriteString(HelpStyle.Render("enter: execute • esc: back • ctrl+g: toggle help"))
} else {
content.WriteString(m.help.View(m.keyMap))
var helpText string
if m.showFullHelp {
helpText = m.help.FullHelpView(m.keyMap.FullHelp())
} else {
helpText = m.help.ShortHelpView(m.keyMap.ShortHelp())
// Add ctrl+g to short help
helpText += " • " + HelpStyle.Render("ctrl+g: toggle help")
}
content.WriteString(helpText)
}
return content.String()

View File

@@ -2,7 +2,10 @@ package app
import "github.com/charmbracelet/bubbles/key"
// QueryKeyMap defines keybindings for the query view
// QueryKeyMap defines keybindings for the query view.
// Navigation follows vim-like patterns:
// - gg: go to start (requires two 'g' presses)
// - G: go to end (single 'G' press)
type QueryKeyMap struct {
// Input mode keys
Execute key.Binding
@@ -100,7 +103,7 @@ func DefaultQueryKeyMap() QueryKeyMap {
// ShortHelp returns keybindings to be shown in the mini help view
func (k QueryKeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Execute, k.Up, k.Down, k.Enter}
return []key.Binding{k.Execute, k.Up, k.Down, k.GoToStart, k.GoToEnd, k.EditQuery}
}
// FullHelp returns keybindings for the expanded help view

View File

@@ -10,15 +10,16 @@ import (
)
type RowDetailModel struct {
Shared *SharedData
rowIndex int
selectedCol int
FromQuery bool
gPressed bool
keyMap RowDetailKeyMap
help help.Model
focused bool
id int
Shared *SharedData
rowIndex int
selectedCol int
FromQuery bool
gPressed bool
keyMap RowDetailKeyMap
help help.Model
showFullHelp bool
focused bool
id int
}
// RowDetailOption is a functional option for configuring RowDetailModel
@@ -81,6 +82,10 @@ func (m *RowDetailModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
switch msg := msg.(type) {
case ToggleHelpMsg:
m.showFullHelp = !m.showFullHelp
return m, nil
case tea.KeyMsg:
return m.handleNavigation(msg)
}
@@ -98,17 +103,17 @@ func (m *RowDetailModel) handleNavigation(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keyMap.GoToStart):
if m.gPressed {
// Second g - go to beginning
// Second g - go to beginning (gg pattern like vim)
m.selectedCol = 0
m.gPressed = false
} else {
// First g - wait for second g
// First g - wait for second g to complete gg sequence
m.gPressed = true
}
return m, nil
case key.Matches(msg, m.keyMap.GoToEnd):
// Go to end
// Go to end (G pattern like vim)
if len(m.Shared.Columns) > 0 {
m.selectedCol = len(m.Shared.Columns) - 1
}
@@ -176,7 +181,15 @@ func (m *RowDetailModel) View() string {
}
content.WriteString("\n")
content.WriteString(m.help.View(m.keyMap))
var helpText string
if m.showFullHelp {
helpText = m.help.FullHelpView(m.keyMap.FullHelp())
} else {
helpText = m.help.ShortHelpView(m.keyMap.ShortHelp())
// Add ctrl+g to short help
helpText += " • " + HelpStyle.Render("ctrl+g: toggle help")
}
content.WriteString(helpText)
return content.String()
}

View File

@@ -2,7 +2,10 @@ package app
import "github.com/charmbracelet/bubbles/key"
// RowDetailKeyMap defines keybindings for the row detail view
// RowDetailKeyMap defines keybindings for the row detail view.
// Navigation follows vim-like patterns:
// - gg: go to start (requires two 'g' presses)
// - G: go to end (single 'G' press)
type RowDetailKeyMap struct {
Up key.Binding
Down key.Binding
@@ -49,7 +52,7 @@ func DefaultRowDetailKeyMap() RowDetailKeyMap {
// ShortHelp returns keybindings to be shown in the mini help view
func (k RowDetailKeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Up, k.Down, k.Enter, k.Back}
return []key.Binding{k.Up, k.Down, k.Enter, k.GoToStart, k.GoToEnd, k.Back}
}
// FullHelp returns keybindings for the expanded help view

View File

@@ -12,15 +12,16 @@ import (
)
type TableDataModel struct {
Shared *SharedData
searchInput textinput.Model
searching bool
selectedRow int
gPressed bool
keyMap TableDataKeyMap
help help.Model
focused bool
id int
Shared *SharedData
searchInput textinput.Model
searching bool
selectedRow int
gPressed bool
keyMap TableDataKeyMap
help help.Model
showFullHelp bool
focused bool
id int
}
// TableDataOption is a functional option for configuring TableDataModel
@@ -93,6 +94,10 @@ func (m *TableDataModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case ToggleHelpMsg:
m.showFullHelp = !m.showFullHelp
return m, nil
case tea.KeyMsg:
if m.searching {
return m.handleSearchInput(msg)
@@ -151,20 +156,20 @@ func (m *TableDataModel) handleNavigation(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keyMap.GoToStart):
if m.gPressed {
// Second g - go to absolute beginning
// Second g - go to absolute beginning (gg pattern like vim)
m.Shared.CurrentPage = 0
m.Shared.LoadTableData()
m.filterData()
m.selectedRow = 0
m.gPressed = false
} else {
// First g - wait for second g
// First g - wait for second g to complete gg sequence
m.gPressed = true
}
return m, nil
case key.Matches(msg, m.keyMap.GoToEnd):
// Go to absolute end
// Go to absolute end (G pattern like vim)
maxPage := (m.Shared.TotalRows - 1) / PageSize
m.Shared.CurrentPage = maxPage
m.Shared.LoadTableData()
@@ -440,7 +445,15 @@ func (m *TableDataModel) View() string {
if m.searching {
content.WriteString(HelpStyle.Render("Type to search • enter/esc: finish search"))
} else {
content.WriteString(m.help.View(m.keyMap))
var helpText string
if m.showFullHelp {
helpText = m.help.FullHelpView(m.keyMap.FullHelp())
} else {
helpText = m.help.ShortHelpView(m.keyMap.ShortHelp())
// Add ctrl+g to short help
helpText += " • " + HelpStyle.Render("ctrl+g: toggle help")
}
content.WriteString(helpText)
}
return content.String()

View File

@@ -2,7 +2,10 @@ package app
import "github.com/charmbracelet/bubbles/key"
// TableDataKeyMap defines keybindings for the table data view
// TableDataKeyMap defines keybindings for the table data view.
// Navigation follows vim-like patterns:
// - gg: go to start (requires two 'g' presses)
// - G: go to end (single 'G' press)
type TableDataKeyMap struct {
Up key.Binding
Down key.Binding
@@ -74,7 +77,7 @@ func DefaultTableDataKeyMap() TableDataKeyMap {
// ShortHelp returns keybindings to be shown in the mini help view
func (k TableDataKeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Up, k.Down, k.Enter, k.Search}
return []key.Binding{k.Up, k.Down, k.Enter, k.GoToStart, k.GoToEnd, k.Search}
}
// FullHelp returns keybindings for the expanded help view

View File

@@ -20,6 +20,7 @@ type TableListModel struct {
gPressed bool
keyMap TableListKeyMap
help help.Model
showFullHelp bool
focused bool
id int
}
@@ -95,6 +96,10 @@ func (m *TableListModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case ToggleHelpMsg:
m.showFullHelp = !m.showFullHelp
return m, nil
case tea.KeyMsg:
if m.searching {
return m.handleSearchInput(msg)
@@ -162,18 +167,18 @@ func (m *TableListModel) handleNavigation(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keyMap.GoToStart):
if m.gPressed {
// Second g - go to beginning
// Second g - go to beginning (gg pattern like vim)
m.selectedTable = 0
m.currentPage = 0
m.gPressed = false
} else {
// First g - wait for second g
// First g - wait for second g to complete gg sequence
m.gPressed = true
}
return m, nil
case key.Matches(msg, m.keyMap.GoToEnd):
// Go to end
// Go to end (G pattern like vim)
if len(m.Shared.FilteredTables) > 0 {
m.selectedTable = len(m.Shared.FilteredTables) - 1
m.adjustPage()
@@ -406,7 +411,15 @@ func (m *TableListModel) View() string {
if m.searching {
content.WriteString(HelpStyle.Render("Type to search • enter/esc: finish search"))
} else {
content.WriteString(m.help.View(m.keyMap))
var helpText string
if m.showFullHelp {
helpText = m.help.FullHelpView(m.keyMap.FullHelp())
} else {
helpText = m.help.ShortHelpView(m.keyMap.ShortHelp())
// Add ctrl+g to short help
helpText += " • " + HelpStyle.Render("ctrl+g: toggle help")
}
content.WriteString(helpText)
}
return content.String()

View File

@@ -2,7 +2,10 @@ package app
import "github.com/charmbracelet/bubbles/key"
// TableListKeyMap defines keybindings for the table list view
// TableListKeyMap defines keybindings for the table list view.
// Navigation follows vim-like patterns:
// - gg: go to start (requires two 'g' presses)
// - G: go to end (single 'G' press)
type TableListKeyMap struct {
Up key.Binding
Down key.Binding
@@ -69,7 +72,7 @@ func DefaultTableListKeyMap() TableListKeyMap {
// ShortHelp returns keybindings to be shown in the mini help view
func (k TableListKeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Up, k.Down, k.Enter, k.Search}
return []key.Binding{k.Up, k.Down, k.Enter, k.GoToStart, k.GoToEnd, k.Search}
}
// FullHelp returns keybindings for the expanded help view