fix(config): resolve enter key submission and keybinding issues (#89)
closes #88 closes #85
This commit is contained in:
@@ -272,3 +272,29 @@ func TestMigration(t *testing.T) {
|
|||||||
t.Errorf("expected backup file update_state.json.bak to exist")
|
t.Errorf("expected backup file update_state.json.bak to exist")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMatchKey(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input []byte
|
||||||
|
expected string
|
||||||
|
matched bool
|
||||||
|
consumed int
|
||||||
|
}{
|
||||||
|
{[]byte{0x19}, "ctrl+y", true, 1},
|
||||||
|
{[]byte{0x0b}, "ctrl+k", true, 1},
|
||||||
|
{[]byte{0x0a}, "ctrl+j", true, 1},
|
||||||
|
{[]byte{0x12}, "ctrl+r", true, 1},
|
||||||
|
{[]byte{'j'}, "j", true, 1},
|
||||||
|
{[]byte{'k'}, "k", true, 1},
|
||||||
|
{[]byte{0x09}, "tab", true, 1},
|
||||||
|
{[]byte{0x0d}, "enter", true, 1},
|
||||||
|
{[]byte{0x0d}, "ctrl+r", false, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
m, c := MatchKey(tt.input, tt.expected)
|
||||||
|
if m != tt.matched || c != tt.consumed {
|
||||||
|
t.Errorf("MatchKey(%v, %q) = (%v, %d); want (%v, %d)", tt.input, tt.expected, m, c, tt.matched, tt.consumed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,15 @@ func MatchKey(input []byte, expected string) (matched bool, consumed int) {
|
|||||||
expected = strings.ToLower(strings.TrimSpace(expected))
|
expected = strings.ToLower(strings.TrimSpace(expected))
|
||||||
expected = strings.TrimPrefix(expected, "<")
|
expected = strings.TrimPrefix(expected, "<")
|
||||||
expected = strings.TrimSuffix(expected, ">")
|
expected = strings.TrimSuffix(expected, ">")
|
||||||
|
expected = strings.ReplaceAll(expected, "-", "+")
|
||||||
|
expected = strings.ReplaceAll(expected, "ctrk", "ctrl")
|
||||||
|
expected = strings.ReplaceAll(expected, "ctl", "ctrl")
|
||||||
|
|
||||||
|
if len(expected) == 1 {
|
||||||
|
if input[0] == expected[0] {
|
||||||
|
return true, 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(expected, "ctrl+") && len(expected) == 6 {
|
if strings.HasPrefix(expected, "ctrl+") && len(expected) == 6 {
|
||||||
char := expected[5]
|
char := expected[5]
|
||||||
|
|||||||
+19
-9
@@ -747,18 +747,24 @@ func runWrapper() {
|
|||||||
|
|
||||||
i += navConsumed - 1
|
i += navConsumed - 1
|
||||||
continue
|
continue
|
||||||
} else if naiveBuffer == "" {
|
} else {
|
||||||
// up/down arrow on empty prompt
|
// up/down arrow or navigation key when overlay is closed
|
||||||
intercepted = true
|
intercepted = true
|
||||||
activeModeMu.Lock()
|
activeModeMu.Lock()
|
||||||
activeMode = "history"
|
if activeMode == "" {
|
||||||
saveMode(activeMode)
|
activeMode = loadMode()
|
||||||
|
}
|
||||||
activeModeMu.Unlock()
|
activeModeMu.Unlock()
|
||||||
|
|
||||||
activeModeMu.RLock()
|
activeModeMu.RLock()
|
||||||
currentMode := activeMode
|
currentMode := activeMode
|
||||||
activeModeMu.RUnlock()
|
activeModeMu.RUnlock()
|
||||||
results := MergeResults("", currentMode)
|
|
||||||
|
bufferMu.Lock()
|
||||||
|
bufQuery := naiveBuffer
|
||||||
|
bufferMu.Unlock()
|
||||||
|
|
||||||
|
results := MergeResults(bufQuery, currentMode)
|
||||||
if len(results) > 0 {
|
if len(results) > 0 {
|
||||||
limit := min(len(results), 100)
|
limit := min(len(results), 100)
|
||||||
var historyList []spec.Suggestion
|
var historyList []spec.Suggestion
|
||||||
@@ -791,8 +797,8 @@ func runWrapper() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if matched, consumed := config.MatchKey(inputSlice[i:], config.Get().Keybindings.SelectSuggestion); matched && config.Get().Keybindings.SelectSuggestion != "" {
|
if matched, consumed := config.MatchKey(inputSlice[i:], config.Get().Keybindings.SelectSuggestion); matched && config.Get().Keybindings.SelectSuggestion != "" {
|
||||||
intercepted = true
|
|
||||||
if overlay.IsVisible() {
|
if overlay.IsVisible() {
|
||||||
|
intercepted = true
|
||||||
selected := overlay.GetCurrentCmd()
|
selected := overlay.GetCurrentCmd()
|
||||||
if selected != "" {
|
if selected != "" {
|
||||||
activeModeMu.RLock()
|
activeModeMu.RLock()
|
||||||
@@ -816,18 +822,22 @@ func runWrapper() {
|
|||||||
userNavigated.Store(false)
|
userNavigated.Store(false)
|
||||||
writeStdout([]byte(overlay.Render()))
|
writeStdout([]byte(overlay.Render()))
|
||||||
}
|
}
|
||||||
|
i += consumed - 1
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
i += consumed - 1
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if b == 0x0d || b == 0x0a { // enter
|
if b == 0x0d || b == 0x0a { // enter
|
||||||
intercepted = true
|
intercepted = true
|
||||||
logger.Debugf("Intercepted Enter key")
|
logger.Debugf("Intercepted Enter key")
|
||||||
|
|
||||||
|
if b == 0x0d && i+1 < n && inputSlice[i+1] == 0x0a {
|
||||||
|
i++ // consume trailing \n in \r\n to prevent matching ctrl+j
|
||||||
|
}
|
||||||
|
|
||||||
var selectedCmd string
|
var selectedCmd string
|
||||||
var shouldAutoExecute bool
|
var shouldAutoExecute bool
|
||||||
if config.Get().Core.AutoExecute && overlay.IsVisible() {
|
if overlay.IsVisible() && (config.Get().Core.AutoExecute || userNavigated.Load()) {
|
||||||
selectedCmd = overlay.GetCurrentCmd()
|
selectedCmd = overlay.GetCurrentCmd()
|
||||||
if selectedCmd != "" {
|
if selectedCmd != "" {
|
||||||
shouldAutoExecute = true
|
shouldAutoExecute = true
|
||||||
|
|||||||
Reference in New Issue
Block a user