Skip to content

Commit

Permalink
fix: input to use latest /ansi (#295)
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
caarlos0 authored Dec 5, 2024
1 parent 76a7089 commit e25cd30
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 48 deletions.
7 changes: 3 additions & 4 deletions input/da1.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ type PrimaryDeviceAttributesEvent []uint
func parsePrimaryDevAttrs(csi *ansi.CsiSequence) Event {
// Primary Device Attributes
da1 := make(PrimaryDeviceAttributesEvent, len(csi.Params))
csi.Range(func(i int, p int, hasMore bool) bool {
if !hasMore {
for i, p := range csi.Params {
if !ansi.Parameter(p).HasMore() {
da1[i] = uint(p)
}
return true
})
}
return da1
}
3 changes: 2 additions & 1 deletion input/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ module github.com/charmbracelet/x/input
go 1.18

require (
github.com/charmbracelet/x/ansi v0.4.5
github.com/charmbracelet/x/ansi v0.5.3-0.20241204155720-fa6b43c98350
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f
github.com/muesli/cancelreader v0.2.2
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e
golang.org/x/sys v0.28.0
)

require (
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
)
4 changes: 4 additions & 0 deletions input/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM=
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/ansi v0.5.3-0.20241204155720-fa6b43c98350 h1:LEZviFqdD7htj5oKO6o053ko6s1H+LAiOd0nbKZa1cE=
github.com/charmbracelet/x/ansi v0.5.3-0.20241204155720-fa6b43c98350/go.mod h1:KBUFw1la39nl0dLl10l5ORDAqGXaeurTQmwyyVKse/Q=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
Expand Down
10 changes: 8 additions & 2 deletions input/kitty.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"unicode/utf8"

"github.com/charmbracelet/x/ansi"
"github.com/charmbracelet/x/ansi/parser"
)

// KittyKeyboardEvent represents Kitty keyboard progressive enhancement flags.
Expand Down Expand Up @@ -213,7 +214,11 @@ func parseKittyKeyboard(csi *ansi.CsiSequence) Event {
var isRelease bool
key := Key{}

if params := csi.Subparams(0); len(params) > 0 {
pparams := make([]int, 0, len(csi.Params))
for _, p := range csi.Params {
pparams = append(pparams, int(p))
}
if params := parser.Subparams(pparams, 0); len(params) > 0 {
code := params[0]
if sym, ok := kittyKeyMap[code]; ok {
key.Sym = sym
Expand Down Expand Up @@ -253,7 +258,8 @@ func parseKittyKeyboard(csi *ansi.CsiSequence) Event {
}
}
}
if params := csi.Subparams(1); len(params) > 0 {

if params := parser.Subparams(pparams, 1); len(params) > 0 {
mod := params[0]
if mod > 1 {
key.Mod = fromKittyMod(mod - 1)
Expand Down
7 changes: 4 additions & 3 deletions input/mouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ var mouseSGRRegex = regexp.MustCompile(`(\d+);(\d+);(\d+)([Mm])`)
//
// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Extended-coordinates
func parseSGRMouseEvent(csi *ansi.CsiSequence) Event {
x := csi.Param(1)
y := csi.Param(2)
b, _ := csi.Param(0, -1)
x, _ := csi.Param(1, -1)
y, _ := csi.Param(2, -1)
release := csi.Command() == 'm'
mod, btn, _, isMotion := parseMouseButton(csi.Param(0))
mod, btn, _, isMotion := parseMouseButton(b)

// (1,1) is the upper left. We subtract 1 to normalize it to (0,0).
x--
Expand Down
8 changes: 6 additions & 2 deletions input/mouse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,12 @@ func TestParseSGRMouseEvent(t *testing.T) {
re = 'm'
}
return &ansi.CsiSequence{
Params: []int{b, x + 1, y + 1},
Cmd: int(re) | ('<' << parser.MarkerShift),
Params: []ansi.Parameter{
ansi.Parameter(b),
ansi.Parameter(x + 1),
ansi.Parameter(y + 1),
},
Cmd: ansi.Command(int(re) | ('<' << parser.MarkerShift)),
}
}

Expand Down
83 changes: 49 additions & 34 deletions input/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func parseCsi(b []byte) (int, Event) {
}

var csi ansi.CsiSequence
var params [parser.MaxParamsSize]int
var params [parser.MaxParamsSize]ansi.Parameter
var paramsLen int

var i int
Expand All @@ -173,7 +173,7 @@ func parseCsi(b []byte) (int, Event) {

// Initial CSI byte
if i < len(b) && b[i] >= '<' && b[i] <= '?' {
csi.Cmd |= int(b[i]) << parser.MarkerShift
csi.Cmd = ansi.Command(int(csi.Cmd) | int(b[i])<<parser.MarkerShift)
}

// Scan parameter bytes in the range 0x30-0x3F
Expand All @@ -184,7 +184,7 @@ func parseCsi(b []byte) (int, Event) {
params[paramsLen] = 0
}
params[paramsLen] *= 10
params[paramsLen] += int(b[i]) - '0'
params[paramsLen] += ansi.Parameter(int(b[i]) - '0')
}
if b[i] == ':' {
params[paramsLen] |= parser.HasMoreFlag
Expand All @@ -210,7 +210,7 @@ func parseCsi(b []byte) (int, Event) {
}

// Set the intermediate byte
csi.Cmd |= int(intermed) << parser.IntermedShift
csi.Cmd = ansi.Command(int(csi.Cmd) | int(intermed)<<parser.IntermedShift)

// Scan final byte in the range 0x40-0x7E
if i >= len(b) || b[i] < 0x40 || b[i] > 0x7E {
Expand All @@ -228,7 +228,7 @@ func parseCsi(b []byte) (int, Event) {
}

// Add the final byte
csi.Cmd |= int(b[i])
csi.Cmd = ansi.Command(int(csi.Cmd) | int(b[i]))
i++

csi.Params = params[:paramsLen]
Expand All @@ -243,21 +243,26 @@ func parseCsi(b []byte) (int, Event) {
if paramsLen != 2 {
return i, UnknownCsiEvent(b[:i])
}
return i, ReportModeEvent{Mode: csi.Param(0), Value: csi.Param(1)}
mode, _ := csi.Param(0, 0)
value, _ := csi.Param(1, 0)
return i, ReportModeEvent{Mode: mode, Value: value}
}
case 'c':
// Primary Device Attributes
return i, parsePrimaryDevAttrs(&csi)
case 'u':
// Kitty keyboard flags
if param := csi.Param(0); param != -1 {
param, _ := csi.Param(0, -1)
if param != -1 {
return i, KittyKeyboardEvent(param)
}
case 'R':
// This report may return a third parameter representing the page
// number, but we don't really need it.
if paramsLen >= 2 {
return i, CursorPositionEvent{Row: csi.Param(0), Column: csi.Param(1)}
row, _ := csi.Param(0, 0)
col, _ := csi.Param(1, 0)
return i, CursorPositionEvent{Row: row, Column: col}
}
}
return i, UnknownCsiEvent(b[:i])
Expand All @@ -276,11 +281,13 @@ func parseCsi(b []byte) (int, Event) {
switch cmd {
case 'm':
// XTerm modifyOtherKeys
if paramsLen != 2 || csi.Param(0) != 4 {
p0, _ := csi.Param(0, 0)
if paramsLen != 2 || p0 != 4 {
return i, UnknownCsiEvent(b[:i])
}

return i, ModifyOtherKeysEvent(csi.Param(1))
p1, _ := csi.Param(1, 0)
return i, ModifyOtherKeysEvent(p1)
default:
return i, UnknownCsiEvent(b[:i])
}
Expand Down Expand Up @@ -309,8 +316,10 @@ func parseCsi(b []byte) (int, Event) {
//
// For a non ambiguous cursor position report, use
// [ansi.RequestExtendedCursorPosition] (DECXCPR) instead.
if csi.Param(0) != 1 {
return i, CursorPositionEvent{Row: csi.Param(0), Column: csi.Param(1)}
row, _ := csi.Param(0, 1)
col, _ := csi.Param(1, 1)
if row != 1 {
return i, CursorPositionEvent{Row: row, Column: col}
}

fallthrough
Expand All @@ -332,10 +341,12 @@ func parseCsi(b []byte) (int, Event) {
case 'Z':
k = KeyPressEvent{Sym: KeyTab, Mod: ModShift}
}
if paramsLen > 1 && csi.Param(0) == 1 {
p0, _ := csi.Param(0, 0)
if paramsLen > 1 && p0 == 1 {
// CSI 1 ; <modifiers> A
p1, _ := csi.Param(1, 0)
if paramsLen > 1 {
k.Mod |= KeyMod(csi.Param(1) - 1)
k.Mod |= KeyMod(p1 - 1)
}
}
return i, k
Expand All @@ -350,7 +361,9 @@ func parseCsi(b []byte) (int, Event) {
if paramsLen != 2 {
return i, UnknownCsiEvent(b[:i])
}
return i, ReportModeEvent{Mode: csi.Param(0), Value: csi.Param(1)}
mod, _ := csi.Param(0, 0)
value, _ := csi.Param(1, 0)
return i, ReportModeEvent{Mode: mod, Value: value}
case 'u':
// Kitty keyboard protocol & CSI u (fixterms)
if paramsLen == 0 {
Expand All @@ -363,18 +376,19 @@ func parseCsi(b []byte) (int, Event) {
return i, UnknownCsiEvent(b[:i])
}

rc := uint16(csi.Param(5))
if rc == 0 {
rc = 1
}

rc, _ := csi.Param(5, 1)
vkc, _ := csi.Param(0, -1)
vsc, _ := csi.Param(1, -1)
uc, _ := csi.Param(2, -1)
kd, _ := csi.Param(3, -1)
cs, _ := csi.Param(4, -1)
event := parseWin32InputKeyEvent(
coninput.VirtualKeyCode(csi.Param(0)), // Vk wVirtualKeyCode
coninput.VirtualKeyCode(csi.Param(1)), // Sc wVirtualScanCode
rune(csi.Param(2)), // Uc UnicodeChar
csi.Param(3) == 1, // Kd bKeyDown
coninput.ControlKeyState(csi.Param(4)), // Cs dwControlKeyState
rc, // Rc wRepeatCount
coninput.VirtualKeyCode(vkc), // Vk VirtualKeyCode
coninput.VirtualKeyCode(vsc), // Sc VirtualScanCode
rune(uc), // Uc UnicodeChar
kd == 1, // Kd bKeyDown
coninput.ControlKeyState(cs), // Cs dwControlKeyState
uint16(rc), // Rc wRepeatCount
)

if event == nil {
Expand All @@ -387,7 +401,7 @@ func parseCsi(b []byte) (int, Event) {
return i, UnknownCsiEvent(b[:i])
}

param := csi.Param(0)
param, _ := csi.Param(0, -1)
switch cmd {
case '~':
switch param {
Expand Down Expand Up @@ -454,7 +468,8 @@ func parseCsi(b []byte) (int, Event) {

// modifiers
if paramsLen > 1 {
k.Mod |= KeyMod(csi.Param(1) - 1)
mod, _ := csi.Param(1, 0)
k.Mod |= KeyMod(mod - 1)
}

// Handle URxvt weird keys
Expand Down Expand Up @@ -669,7 +684,7 @@ func parseDcs(b []byte) (int, Event) {
return 2, KeyPressEvent{Rune: rune(b[1]), Mod: ModAlt}
}

var params [16]int
var params [16]ansi.Parameter
var paramsLen int
var dcs ansi.DcsSequence

Expand All @@ -684,7 +699,7 @@ func parseDcs(b []byte) (int, Event) {

// initial DCS byte
if i < len(b) && b[i] >= '<' && b[i] <= '?' {
dcs.Cmd |= int(b[i]) << parser.MarkerShift
dcs.Cmd = ansi.Command(int(dcs.Cmd) | int(b[i])<<parser.MarkerShift)
}

// Scan parameter bytes in the range 0x30-0x3F
Expand All @@ -695,7 +710,7 @@ func parseDcs(b []byte) (int, Event) {
params[paramsLen] = 0
}
params[paramsLen] *= 10
params[paramsLen] += int(b[i]) - '0'
params[paramsLen] += ansi.Parameter(int(b[i]) - '0')
}
if b[i] == ':' {
params[paramsLen] |= parser.HasMoreFlag
Expand All @@ -721,15 +736,15 @@ func parseDcs(b []byte) (int, Event) {
}

// set intermediate byte
dcs.Cmd |= int(intermed) << parser.IntermedShift
dcs.Cmd = ansi.Command(int(dcs.Cmd) | int(intermed)<<parser.IntermedShift)

// Scan final byte in the range 0x40-0x7E
if i >= len(b) || b[i] < 0x40 || b[i] > 0x7E {
return i, UnknownEvent(b[:i])
}

// Add the final byte
dcs.Cmd |= int(b[i])
dcs.Cmd = ansi.Command(int(dcs.Cmd) | int(b[i]))
i++

start := i // start of the sequence data
Expand Down Expand Up @@ -757,7 +772,7 @@ func parseDcs(b []byte) (int, Event) {
switch dcs.Intermediate() {
case '+':
// XTGETTCAP responses
switch param := dcs.Param(0); param {
switch param, _ := dcs.Param(0, -1); param {
case 0, 1:
tc := parseTermcap(b[start:end])
// XXX: some terminals like KiTTY report invalid responses with
Expand Down
6 changes: 4 additions & 2 deletions input/xterm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (

func parseXTermModifyOtherKeys(csi *ansi.CsiSequence) Event {
// XTerm modify other keys starts with ESC [ 27 ; <modifier> ; <code> ~
mod := KeyMod(csi.Param(1) - 1)
r := rune(csi.Param(2))
m, _ := csi.Param(1, 0)
mod := KeyMod(m - 1)
p, _ := csi.Param(2, 0)
r := rune(p)

switch r {
case ansi.BS:
Expand Down

0 comments on commit e25cd30

Please sign in to comment.