mirror of
https://github.com/jixishi/SerialTerminalForWindowsTerminal.git
synced 2026-06-15 16:42:46 +00:00
e0de872740
Extract ConvertChunk/FormatHexFrame into pkg/charset (zero external deps). Extract UIEvent/UIEventKind/UIPanelKind types into internal/event. Update all references across main package to use qualified imports. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
154 lines
3.4 KiB
Go
154 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/jixishi/SerialTerminalForWindowsTerminal/internal/event"
|
|
)
|
|
|
|
func handleLocalHotkey(m *uiModel, key string) bool {
|
|
if m.isLocalHotkey(key, "h") {
|
|
modifier := strings.ToUpper(normalizeHotkeyPrefix(m.app.cfg.hotkeyMod))
|
|
m.app.ShowModal("Shortcuts", modifier+"+C => local exit\nCtrl+C => remote interrupt\n"+modifier+"+F => forward panel\n"+modifier+"+P => plugin panel\n"+modifier+"+M => mode panel\nF1 => shortcut help")
|
|
return true
|
|
}
|
|
if m.isLocalHotkey(key, "f") {
|
|
m.app.OpenPanel(event.UIPanelForward)
|
|
return true
|
|
}
|
|
if m.isLocalHotkey(key, "p") {
|
|
m.app.OpenPanel(event.UIPanelPlugin)
|
|
return true
|
|
}
|
|
if m.isLocalHotkey(key, "m") {
|
|
m.app.OpenPanel(event.UIPanelMode)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (m *uiModel) isLocalHotkey(key, action string) bool {
|
|
parts := strings.Split(strings.ToLower(key), "+")
|
|
if len(parts) < 2 || parts[len(parts)-1] != action {
|
|
return false
|
|
}
|
|
|
|
hasCtrl := false
|
|
hasAlt := false
|
|
hasShift := false
|
|
for _, p := range parts[:len(parts)-1] {
|
|
switch p {
|
|
case "ctrl":
|
|
hasCtrl = true
|
|
case "alt":
|
|
hasAlt = true
|
|
case "shift":
|
|
hasShift = true
|
|
}
|
|
}
|
|
|
|
mod := normalizeHotkeyPrefix(m.app.cfg.hotkeyMod)
|
|
if mod == "ctrl+shift" {
|
|
return hasCtrl && hasShift
|
|
}
|
|
return hasCtrl && hasAlt
|
|
}
|
|
|
|
func normalizeHotkeyPrefix(mod string) string {
|
|
mod = strings.ToLower(strings.TrimSpace(mod))
|
|
if mod != "ctrl+alt" && mod != "ctrl+shift" {
|
|
mod = "ctrl+alt"
|
|
}
|
|
return mod
|
|
}
|
|
|
|
func hotkeyWith(mod, action string) string {
|
|
return normalizeHotkeyPrefix(mod) + "+" + action
|
|
}
|
|
|
|
func parseCtrlKey(key string) (byte, bool) {
|
|
if !strings.HasPrefix(key, "ctrl+") || strings.HasPrefix(key, "ctrl+shift+") {
|
|
return 0, false
|
|
}
|
|
|
|
parts := strings.Split(key, "+")
|
|
if len(parts) != 2 || len(parts[1]) != 1 {
|
|
return 0, false
|
|
}
|
|
ch := parts[1][0]
|
|
if ch < 'a' || ch > 'z' {
|
|
return 0, false
|
|
}
|
|
return ch, true
|
|
}
|
|
|
|
func (m *uiModel) handleViewportKey(msg tea.KeyMsg) bool {
|
|
if !m.ready || m.showModal {
|
|
return false
|
|
}
|
|
|
|
key := strings.ToLower(msg.String())
|
|
switch key {
|
|
case "pgup", "ctrl+u", "alt+up", "up":
|
|
var cmd tea.Cmd
|
|
m.viewport, cmd = m.viewport.Update(msg)
|
|
_ = cmd
|
|
m.followTail = false
|
|
return true
|
|
case "pgdown", "ctrl+d", "alt+down", "down":
|
|
var cmd tea.Cmd
|
|
m.viewport, cmd = m.viewport.Update(msg)
|
|
_ = cmd
|
|
return true
|
|
case "home", "g":
|
|
m.viewport.GotoTop()
|
|
m.followTail = false
|
|
return true
|
|
case "end", "shift+g":
|
|
m.viewport.GotoBottom()
|
|
m.followTail = true
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (m *uiModel) resetCompletion() {
|
|
m.completionActive = false
|
|
m.completionBase = ""
|
|
m.completionCandidates = nil
|
|
m.completionIndex = 0
|
|
}
|
|
|
|
func (m *uiModel) stepCompletion(direction int) {
|
|
if len(m.completionCandidates) == 0 {
|
|
m.resetCompletion()
|
|
return
|
|
}
|
|
if direction >= 0 {
|
|
m.completionIndex = (m.completionIndex + 1) % len(m.completionCandidates)
|
|
} else {
|
|
m.completionIndex = (m.completionIndex - 1 + len(m.completionCandidates)) % len(m.completionCandidates)
|
|
}
|
|
m.applyCompletion()
|
|
}
|
|
|
|
func (m *uiModel) applyCompletion() {
|
|
if len(m.completionCandidates) == 0 {
|
|
return
|
|
}
|
|
m.input.SetValue(m.completionBase + m.completionCandidates[m.completionIndex] + " ")
|
|
}
|
|
|
|
func completionBase(line string) string {
|
|
if strings.HasSuffix(line, " ") {
|
|
return line
|
|
}
|
|
i := strings.LastIndex(line, " ")
|
|
if i < 0 {
|
|
return ""
|
|
}
|
|
return line[:i+1]
|
|
}
|