mirror of
https://github.com/charmbracelet/crush.git
synced 2025-08-02 05:20:46 +03:00
feat(tui): completions: add select and insert keybinds
This adds keybinds to select next/previous completion item using ctrl+p and ctrl+n similar to Vim's completion behavior.
This commit is contained in:
@@ -187,9 +187,11 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
value = value[:m.completionsStartIndex]
|
||||
value += item.Path
|
||||
m.textarea.SetValue(value)
|
||||
m.isCompletionsOpen = false
|
||||
m.currentQuery = ""
|
||||
m.completionsStartIndex = 0
|
||||
if !msg.Insert {
|
||||
m.isCompletionsOpen = false
|
||||
m.currentQuery = ""
|
||||
m.completionsStartIndex = 0
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
case openEditorMsg:
|
||||
|
||||
@@ -36,7 +36,8 @@ type CompletionsOpenedMsg struct{}
|
||||
type CloseCompletionsMsg struct{}
|
||||
|
||||
type SelectCompletionMsg struct {
|
||||
Value any // The value of the selected completion item
|
||||
Value any // The value of the selected completion item
|
||||
Insert bool
|
||||
}
|
||||
|
||||
type Completions interface {
|
||||
@@ -115,6 +116,30 @@ func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
d, cmd := c.list.Update(msg)
|
||||
c.list = d.(list.ListModel)
|
||||
return c, cmd
|
||||
case key.Matches(msg, c.keyMap.UpInsert):
|
||||
selectedItemInx := c.list.SelectedIndex() - 1
|
||||
items := c.list.Items()
|
||||
if selectedItemInx == list.NoSelection || selectedItemInx < 0 {
|
||||
return c, nil // No item selected, do nothing
|
||||
}
|
||||
selectedItem := items[selectedItemInx].(CompletionItem).Value()
|
||||
c.list.SetSelected(selectedItemInx)
|
||||
return c, util.CmdHandler(SelectCompletionMsg{
|
||||
Value: selectedItem,
|
||||
Insert: true,
|
||||
})
|
||||
case key.Matches(msg, c.keyMap.DownInsert):
|
||||
selectedItemInx := c.list.SelectedIndex() + 1
|
||||
items := c.list.Items()
|
||||
if selectedItemInx == list.NoSelection || selectedItemInx >= len(items) {
|
||||
return c, nil // No item selected, do nothing
|
||||
}
|
||||
selectedItem := items[selectedItemInx].(CompletionItem).Value()
|
||||
c.list.SetSelected(selectedItemInx)
|
||||
return c, util.CmdHandler(SelectCompletionMsg{
|
||||
Value: selectedItem,
|
||||
Insert: true,
|
||||
})
|
||||
case key.Matches(msg, c.keyMap.Select):
|
||||
selectedItemInx := c.list.SelectedIndex()
|
||||
if selectedItemInx == list.NoSelection {
|
||||
|
||||
@@ -9,6 +9,8 @@ type KeyMap struct {
|
||||
Up,
|
||||
Select,
|
||||
Cancel key.Binding
|
||||
DownInsert,
|
||||
UpInsert key.Binding
|
||||
}
|
||||
|
||||
func DefaultKeyMap() KeyMap {
|
||||
@@ -29,6 +31,14 @@ func DefaultKeyMap() KeyMap {
|
||||
key.WithKeys("esc"),
|
||||
key.WithHelp("esc", "cancel"),
|
||||
),
|
||||
DownInsert: key.NewBinding(
|
||||
key.WithKeys("ctrl+n"),
|
||||
key.WithHelp("ctrl+n", "insert next"),
|
||||
),
|
||||
UpInsert: key.NewBinding(
|
||||
key.WithKeys("ctrl+p"),
|
||||
key.WithHelp("ctrl+p", "insert previous"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -319,26 +319,20 @@ func (a *appModel) handleWindowResize(width, height int) tea.Cmd {
|
||||
|
||||
// handleKeyPressMsg processes keyboard input and routes to appropriate handlers.
|
||||
func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
|
||||
if a.completions.Open() {
|
||||
// completions
|
||||
keyMap := a.completions.KeyMap()
|
||||
switch {
|
||||
case key.Matches(msg, keyMap.Up), key.Matches(msg, keyMap.Down),
|
||||
key.Matches(msg, keyMap.Select), key.Matches(msg, keyMap.Cancel),
|
||||
key.Matches(msg, keyMap.UpInsert), key.Matches(msg, keyMap.DownInsert):
|
||||
u, cmd := a.completions.Update(msg)
|
||||
a.completions = u.(completions.Completions)
|
||||
return cmd
|
||||
}
|
||||
}
|
||||
switch {
|
||||
// completions
|
||||
case a.completions.Open() && key.Matches(msg, a.completions.KeyMap().Up):
|
||||
u, cmd := a.completions.Update(msg)
|
||||
a.completions = u.(completions.Completions)
|
||||
return cmd
|
||||
|
||||
case a.completions.Open() && key.Matches(msg, a.completions.KeyMap().Down):
|
||||
u, cmd := a.completions.Update(msg)
|
||||
a.completions = u.(completions.Completions)
|
||||
return cmd
|
||||
case a.completions.Open() && key.Matches(msg, a.completions.KeyMap().Select):
|
||||
u, cmd := a.completions.Update(msg)
|
||||
a.completions = u.(completions.Completions)
|
||||
return cmd
|
||||
case a.completions.Open() && key.Matches(msg, a.completions.KeyMap().Cancel):
|
||||
u, cmd := a.completions.Update(msg)
|
||||
a.completions = u.(completions.Completions)
|
||||
return cmd
|
||||
// help
|
||||
// help
|
||||
case key.Matches(msg, a.keyMap.Help):
|
||||
a.status.ToggleFullHelp()
|
||||
a.showingFullHelp = !a.showingFullHelp
|
||||
|
||||
Reference in New Issue
Block a user