fix: simplify forward form to 2 fields, fix centering

- Revert fillScreen to Left/Top (normal terminal behavior)
- Simplify startForwardForm to 2 fields: Type (Tab cycle) + Address
- Remove splitAddr/netSplit helpers
- Add huh form library dependency for future use

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
JiXieShi
2026-05-24 02:23:48 +08:00
parent 939c3d5a29
commit 7b6f4f03ab
3 changed files with 40 additions and 69 deletions
+20 -15
View File
@@ -1,18 +1,18 @@
module github.com/jixishi/SerialTerminalForWindowsTerminal
go 1.22
go 1.23.0
require (
github.com/charmbracelet/bubbles v0.18.0
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/lipgloss v0.9.1
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7
github.com/charmbracelet/bubbletea v1.3.6
github.com/charmbracelet/lipgloss v1.1.0
github.com/fzdwx/infinite v0.12.1
github.com/spf13/pflag v1.0.5
github.com/trzsz/trzsz-go v1.1.7
github.com/yuin/gopher-lua v1.1.1
github.com/zimolab/charsetconv v0.1.2
go.bug.st/serial v1.6.2
golang.org/x/sys v0.19.0
golang.org/x/sys v0.33.0
golang.org/x/term v0.19.0
)
@@ -22,32 +22,37 @@ require (
github.com/alexflint/go-scalar v1.2.0 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.9.3 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/creack/goselect v0.1.2 // indirect
github.com/creack/pty v1.1.21 // indirect
github.com/creack/pty v1.1.24 // indirect
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f // indirect
github.com/duke-git/lancet/v2 v2.2.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fzdwx/iter v0.0.0-20230511075109-0afee9319312 // indirect
github.com/josephspurrier/goversioninfo v1.4.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/ncruces/zenity v0.10.10 // indirect
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 // indirect
github.com/rivo/uniseg v0.4.6 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rotisserie/eris v0.5.4 // indirect
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/trzsz/go-arg v1.5.3 // indirect
github.com/trzsz/promptui v0.10.5 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/text v0.23.0 // indirect
)
+19 -53
View File
@@ -111,7 +111,7 @@ func (m *Model) handleForwardPanelKey(key string) bool {
m.refreshPanel()
return true
case "a":
m.startForwardForm("Add Forward", "tcp", "", "")
m.startForwardForm("Add", "tcp", "")
return true
}
if len(m.forwardItems) == 0 {
@@ -142,70 +142,57 @@ func (m *Model) handleForwardPanelKey(key string) bool {
})
return true
case "u":
addr, port := splitAddr(sel.Address)
m.startForwardForm("Update Forward #"+fmt.Sprint(sel.ID), sel.Mode, addr, port)
m.startForwardForm("Update #"+fmt.Sprint(sel.ID), sel.Mode, sel.Address)
return true
default:
return true
}
}
func (m *Model) startForwardForm(title, mode, addr, port string) {
// Mode input
func (m *Model) startForwardForm(title, mode, address string) {
modeIn := textinput.New()
modeIn.Prompt = " Type: "
modeIn.Placeholder = "Tab to cycle"
modeIn.Placeholder = "Tab to cycle modes"
modeIn.SetValue(mode)
modeIn.CharLimit = 20
modeIn.Width = 40
modeIn.CharLimit = 10
modeIn.Width = 36
// Address input
addrIn := textinput.New()
addrIn.Prompt = " Host: "
addrIn.Placeholder = "127.0.0.1 or COM2"
addrIn.SetValue(addr)
addrIn.Prompt = " Addr: "
addrIn.Placeholder = "host:port or COM port"
addrIn.SetValue(address)
addrIn.CharLimit = 60
addrIn.Width = 40
// Port input
portIn := textinput.New()
portIn.Prompt = " Port: "
portIn.Placeholder = "12345"
portIn.SetValue(port)
portIn.CharLimit = 10
portIn.Width = 40
addrIn.Width = 36
m.formActive = true
m.formTitle = title
m.formLabels = []string{"Type", "Host", "Port"}
m.formFields = []textinput.Model{modeIn, addrIn, portIn}
m.formLabels = []string{"Type (Tab cycle)", "Address"}
m.formFields = []textinput.Model{modeIn, addrIn}
m.formFocus = 0
m.formFields[0].Focus()
m.formSubmit = func(vals []string) {
modeStr := strings.TrimSpace(vals[0])
host := strings.TrimSpace(vals[1])
portStr := strings.TrimSpace(vals[2])
addrStr := strings.TrimSpace(vals[1])
fm, ok := forward.ParseMode(modeStr)
if !ok {
m.panelError = "unknown mode: " + modeStr
return
}
address := host
if portStr != "" && fm != forward.COMPort {
address = host + ":" + portStr
if addrStr == "" {
m.panelError = "address is required"
return
}
if title == "Add Forward" {
if _, err := m.App.Forward().Add(fm, address); err != nil {
if strings.HasPrefix(title, "Add") {
if _, err := m.App.Forward().Add(fm, addrStr); err != nil {
m.panelError = err.Error()
return
}
} else {
sel := m.forwardItems[m.panelIndex]
if err := m.App.Forward().Update(sel.ID, fm, address); err != nil {
if err := m.App.Forward().Update(sel.ID, fm, addrStr); err != nil {
m.panelError = err.Error()
return
}
@@ -435,27 +422,6 @@ func (m *Model) renderForm() string {
return renderBox(m.formTitle, lines, 40, m.availableModalWidth())
}
func splitAddr(address string) (host, port string) {
// For COM ports, port is empty
if strings.HasPrefix(strings.ToUpper(address), "COM") {
return address, ""
}
// Try host:port split
if h, p, err := netSplit(address); err == nil {
return h, p
}
return address, ""
}
func netSplit(addr string) (string, string, error) {
for i := len(addr) - 1; i >= 0; i-- {
if addr[i] == ':' {
return addr[:i], addr[i+1:], nil
}
}
return "", "", fmt.Errorf("no port")
}
func (m *Model) handlePromptKey(msg tea.KeyMsg) (bool, tea.Cmd) {
key := strings.ToLower(msg.String())
switch key {
+1 -1
View File
@@ -62,7 +62,7 @@ func fillScreen(width, height int, content string) string {
if width <= 0 || height <= 0 {
return content
}
return lipgloss.Place(width, height, lipgloss.Center, lipgloss.Center, content,
return lipgloss.Place(width, height, lipgloss.Left, lipgloss.Top, content,
lipgloss.WithWhitespaceChars(" "),
lipgloss.WithWhitespaceForeground(lipgloss.Color("0")),
)