Add key binding to select an entry and cd into that directory

This commit is contained in:
David Dworken 2023-05-19 17:14:33 -07:00
parent 79c32e7d51
commit 9f2b392ddb
No known key found for this signature in database
4 changed files with 68 additions and 36 deletions

View File

@ -1959,6 +1959,14 @@ func TestTui(t *testing.T) {
out = strings.TrimSpace(strings.Split(out, "hishtory tquery")[1]) out = strings.TrimSpace(strings.Split(out, "hishtory tquery")[1])
testutils.CompareGoldens(t, out, "TestTui-HelpPageClosed") testutils.CompareGoldens(t, out, "TestTui-HelpPageClosed")
// Test selecting and cd-ing
out = captureTerminalOutput(t, tester, []string{
"hishtory SPACE tquery ENTER",
"C-x",
})
out = strings.Split(strings.TrimSpace(strings.Split(out, "hishtory tquery")[1]), "\n")[0]
testutils.CompareGoldens(t, out, "TestTui-SelectAndCd")
// Assert there are no leaked connections // Assert there are no leaked connections
assertNoLeakedConnections(t) assertNoLeakedConnections(t)
} }

View File

@ -28,3 +28,4 @@ hiSHtory: Search your shell history
↑ scroll up ↓ scroll down pgup page up pgdn page down ↑ scroll up ↓ scroll down pgup page up pgdn page down
← move left → move right shift+← scroll the table left shift+→ scroll the table right ← move left → move right shift+← scroll the table left shift+→ scroll the table right
enter select an entry ctrl+k delete the highlighted entry esc exit hiSHtory ctrl+h help enter select an entry ctrl+k delete the highlighted entry esc exit hiSHtory ctrl+h help
ctrl+x select an entry and cd into that directory

View File

@ -0,0 +1 @@
cd /tmp/; echo '1234567890qwertyuiopasdfghjklzxxcvbnm0987654321_0_1234567890qwertyuiopasdfghjklzxxcvbnm0987654321_1_1234567890qwertyuiopasdfghjklzxxcvbnm0987654321_2_1234567890qwertyuiopasdfghjklzxxcv

View File

@ -26,7 +26,7 @@ import (
const TABLE_HEIGHT = 20 const TABLE_HEIGHT = 20
const PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5 const PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5
var selectedCommand string = "" var SELECTED_COMMAND string = ""
var baseStyle = lipgloss.NewStyle(). var baseStyle = lipgloss.NewStyle().
BorderStyle(lipgloss.NormalBorder()). BorderStyle(lipgloss.NormalBorder()).
@ -38,6 +38,7 @@ type keyMap struct {
PageUp key.Binding PageUp key.Binding
PageDown key.Binding PageDown key.Binding
SelectEntry key.Binding SelectEntry key.Binding
SelectEntryAndChangeDir key.Binding
Left key.Binding Left key.Binding
Right key.Binding Right key.Binding
TableLeft key.Binding TableLeft key.Binding
@ -63,7 +64,7 @@ func (k keyMap) ShortHelp() []key.Binding {
func (k keyMap) FullHelp() [][]key.Binding { func (k keyMap) FullHelp() [][]key.Binding {
return [][]key.Binding{ return [][]key.Binding{
{fakeTitleKeyBinding, k.Up, k.Left, k.SelectEntry}, {fakeTitleKeyBinding, k.Up, k.Left, k.SelectEntry, k.SelectEntryAndChangeDir},
{fakeEmptyKeyBinding, k.Down, k.Right, k.DeleteEntry}, {fakeEmptyKeyBinding, k.Down, k.Right, k.DeleteEntry},
{fakeEmptyKeyBinding, k.PageUp, k.TableLeft, k.Quit}, {fakeEmptyKeyBinding, k.PageUp, k.TableLeft, k.Quit},
{fakeEmptyKeyBinding, k.PageDown, k.TableRight, k.Help}, {fakeEmptyKeyBinding, k.PageDown, k.TableRight, k.Help},
@ -73,54 +74,66 @@ func (k keyMap) FullHelp() [][]key.Binding {
var keys = keyMap{ var keys = keyMap{
Up: key.NewBinding( Up: key.NewBinding(
key.WithKeys("up", "alt+OA", "ctrl+p"), key.WithKeys("up", "alt+OA", "ctrl+p"),
key.WithHelp("↑", "scroll up"), key.WithHelp("↑ ", "scroll up "),
), ),
Down: key.NewBinding( Down: key.NewBinding(
key.WithKeys("down", "alt+OB", "ctrl+n"), key.WithKeys("down", "alt+OB", "ctrl+n"),
key.WithHelp("↓", "scroll down"), key.WithHelp("↓ ", "scroll down "),
), ),
PageUp: key.NewBinding( PageUp: key.NewBinding(
key.WithKeys("pgup"), key.WithKeys("pgup"),
key.WithHelp("pgup", "page up"), key.WithHelp("pgup", "page up "),
), ),
PageDown: key.NewBinding( PageDown: key.NewBinding(
key.WithKeys("pgdown"), key.WithKeys("pgdown"),
key.WithHelp("pgdn", "page down"), key.WithHelp("pgdn", "page down "),
), ),
SelectEntry: key.NewBinding( SelectEntry: key.NewBinding(
key.WithKeys("enter"), key.WithKeys("enter"),
key.WithHelp("enter", "select an entry"), key.WithHelp("enter", "select an entry "),
),
SelectEntryAndChangeDir: key.NewBinding(
key.WithKeys("ctrl+x"),
key.WithHelp("ctrl+x", "select an entry and cd into that directory"),
), ),
Left: key.NewBinding( Left: key.NewBinding(
key.WithKeys("left"), key.WithKeys("left"),
key.WithHelp("←", "move left"), key.WithHelp("← ", "move left "),
), ),
Right: key.NewBinding( Right: key.NewBinding(
key.WithKeys("right"), key.WithKeys("right"),
key.WithHelp("→", "move right"), key.WithHelp("→ ", "move right "),
), ),
TableLeft: key.NewBinding( TableLeft: key.NewBinding(
key.WithKeys("shift+left"), key.WithKeys("shift+left"),
key.WithHelp("shift+←", "scroll the table left"), key.WithHelp("shift+← ", "scroll the table left "),
), ),
TableRight: key.NewBinding( TableRight: key.NewBinding(
key.WithKeys("shift+right"), key.WithKeys("shift+right"),
key.WithHelp("shift+→", "scroll the table right"), key.WithHelp("shift+→ ", "scroll the table right "),
), ),
DeleteEntry: key.NewBinding( DeleteEntry: key.NewBinding(
key.WithKeys("ctrl+k"), key.WithKeys("ctrl+k"),
key.WithHelp("ctrl+k", "delete the highlighted entry"), key.WithHelp("ctrl+k", "delete the highlighted entry "),
), ),
Help: key.NewBinding( Help: key.NewBinding(
key.WithKeys("ctrl+h"), key.WithKeys("ctrl+h"),
key.WithHelp("ctrl+h", "help"), key.WithHelp("ctrl+h", "help "),
), ),
Quit: key.NewBinding( Quit: key.NewBinding(
key.WithKeys("esc", "ctrl+c", "ctrl+d"), key.WithKeys("esc", "ctrl+c", "ctrl+d"),
key.WithHelp("esc", "exit hiSHtory"), key.WithHelp("esc", "exit hiSHtory "),
), ),
} }
type SelectStatus int64
const (
NotSelected SelectStatus = iota
Selected
SelectedWithChangeDir
)
type model struct { type model struct {
// context // context
ctx *context.Context ctx *context.Context
@ -141,7 +154,7 @@ type model struct {
// The entries in the table // The entries in the table
tableEntries []*data.HistoryEntry 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 SelectStatus
// The search box for the query // The search box for the query
queryInput textinput.Model queryInput textinput.Model
@ -226,7 +239,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit return m, tea.Quit
case key.Matches(msg, keys.SelectEntry): case key.Matches(msg, keys.SelectEntry):
if len(m.tableEntries) != 0 { if len(m.tableEntries) != 0 {
m.selected = true m.selected = Selected
}
return m, tea.Quit
case key.Matches(msg, keys.SelectEntryAndChangeDir):
if len(m.tableEntries) != 0 {
m.selected = SelectedWithChangeDir
} }
return m, tea.Quit return m, tea.Quit
case key.Matches(msg, keys.DeleteEntry): case key.Matches(msg, keys.DeleteEntry):
@ -282,8 +300,12 @@ func (m model) View() string {
if m.fatalErr != nil { if m.fatalErr != nil {
return fmt.Sprintf("An unrecoverable error occured: %v\n", m.fatalErr) return fmt.Sprintf("An unrecoverable error occured: %v\n", m.fatalErr)
} }
if m.selected { if m.selected == Selected || m.selected == SelectedWithChangeDir {
selectedCommand = m.tableEntries[m.table.Cursor()].Command SELECTED_COMMAND = m.tableEntries[m.table.Cursor()].Command
if m.selected == SelectedWithChangeDir {
changeDir := m.tableEntries[m.table.Cursor()].CurrentWorkingDirectory
SELECTED_COMMAND = "cd " + changeDir + "; " + SELECTED_COMMAND
}
return "" return ""
} }
if m.quitting { if m.quitting {
@ -560,10 +582,10 @@ func TuiQuery(ctx *context.Context, initialQuery string) error {
if err != nil { if err != nil {
return err return err
} }
if selectedCommand == "" && os.Getenv("HISHTORY_TERM_INTEGRATION") != "" { if SELECTED_COMMAND == "" && os.Getenv("HISHTORY_TERM_INTEGRATION") != "" {
// Print out the initialQuery instead so that we don't clear the terminal // Print out the initialQuery instead so that we don't clear the terminal
selectedCommand = initialQuery SELECTED_COMMAND = initialQuery
} }
fmt.Printf("%s\n", strings.ReplaceAll(selectedCommand, "\\n", "\n")) fmt.Printf("%s\n", strings.ReplaceAll(SELECTED_COMMAND, "\\n", "\n"))
return nil return nil
} }