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

@ -25,6 +25,7 @@ Search Query: > ls
│ │ │ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
hiSHtory: Search your shell history 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,25 +26,26 @@ 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()).
BorderForeground(lipgloss.Color("240")) BorderForeground(lipgloss.Color("240"))
type keyMap struct { type keyMap struct {
Up key.Binding Up key.Binding
Down key.Binding Down key.Binding
PageUp key.Binding PageUp key.Binding
PageDown key.Binding PageDown key.Binding
SelectEntry key.Binding SelectEntry key.Binding
Left key.Binding SelectEntryAndChangeDir key.Binding
Right key.Binding Left key.Binding
TableLeft key.Binding Right key.Binding
TableRight key.Binding TableLeft key.Binding
DeleteEntry key.Binding TableRight key.Binding
Help key.Binding DeleteEntry key.Binding
Quit key.Binding Help key.Binding
Quit key.Binding
} }
var fakeTitleKeyBinding key.Binding = key.NewBinding( var fakeTitleKeyBinding key.Binding = key.NewBinding(
@ -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
} }