Skip to content

Commit

Permalink
Merge branch 'johan/fix-paste'
Browse files Browse the repository at this point in the history
Fixes #73
  • Loading branch information
walles committed Jan 11, 2023
2 parents d95a57c + e8a948a commit 49f876b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 18 deletions.
42 changes: 24 additions & 18 deletions twin/screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,41 +260,47 @@ func consumeEncodedEvent(encodedEventSequences string) (*Event, string) {

mouseMatch := MOUSE_EVENT_REGEX.FindStringSubmatch(encodedEventSequences)
if mouseMatch != nil {
if mouseMatch[1] == "65" {
var event Event = EventMouse{buttons: MouseWheelDown}
return &event, strings.TrimPrefix(encodedEventSequences, mouseMatch[0])
}
if mouseMatch[1] == "64" {
var event Event = EventMouse{buttons: MouseWheelUp}
return &event, strings.TrimPrefix(encodedEventSequences, mouseMatch[0])
}
if mouseMatch[1] == "65" {
var event Event = EventMouse{buttons: MouseWheelDown}
return &event, strings.TrimPrefix(encodedEventSequences, mouseMatch[0])
}

log.Debug("Unhandled multi character mouse escape sequence(s): ", encodedEventSequences)
return nil, ""
}

// No escape sequence prefix matched
runes := []rune(encodedEventSequences)
if len(runes) != 1 {
// This means one or more sequences should be added to
// escapeSequenceToKeyCode in keys.go.
log.Debug("Unhandled multi character terminal escape sequence(s): ", encodedEventSequences)

// Mark everything as consumed since we don't know how to proceed otherwise.
if len(runes) == 0 {
return nil, ""
}

var event Event
if runes[0] == '\x1b' {
event = EventKeyCode{KeyEscape}
} else if runes[0] == '\r' {
event = EventKeyCode{KeyEnter}
} else {
// Report the single rune
event = EventRune{rune: runes[0]}
if len(runes) != 1 {
// This means one or more sequences should be added to
// escapeSequenceToKeyCode in keys.go.
log.Debug("Unhandled multi character terminal escape sequence(s): ", encodedEventSequences)

// Mark everything as consumed since we don't know how to proceed otherwise.
return nil, ""
}

var event Event = EventKeyCode{KeyEscape}
return &event, string(runes[1:])
}

if runes[0] == '\r' {
var event Event = EventKeyCode{KeyEnter}
return &event, string(runes[1:])
}

return &event, ""
// Report the single rune
var event Event = EventRune{rune: runes[0]}
return &event, string(runes[1:])
}

// Returns screen width and height.
Expand Down
50 changes: 50 additions & 0 deletions twin/screen_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package twin

import (
"strings"
"testing"

"gotest.tools/v3/assert"
)

func assertEncode(t *testing.T, incomingString string, expectedEvent Event, expectedRemainder string) {
actualEvent, actualRemainder := consumeEncodedEvent(incomingString)

message := strings.Replace(incomingString, "\x1b", "ESC", -1)
message = strings.Replace(message, "\r", "RET", -1)

assert.Assert(t, actualEvent != nil,
"Input: %s Result: %#v Expected: %#v", message, "nil", expectedEvent)
assert.Equal(t, *actualEvent, expectedEvent,
"Input: %s Result: %#v Expected: %#v", message, *actualEvent, expectedEvent)
assert.Equal(t, actualRemainder, expectedRemainder, message)
}

func TestConsumeEncodedEvent(t *testing.T) {
assertEncode(t, "a", EventRune{rune: 'a'}, "")
assertEncode(t, "\r", EventKeyCode{keyCode: KeyEnter}, "")
assertEncode(t, "\x1b", EventKeyCode{keyCode: KeyEscape}, "")

// Implicitly test having a remaining rune at the end
assertEncode(t, "\x1b[Ax", EventKeyCode{keyCode: KeyUp}, "x")

assertEncode(t, "\x1b[<64;127;41M", EventMouse{buttons: MouseWheelUp}, "")
assertEncode(t, "\x1b[<65;127;41M", EventMouse{buttons: MouseWheelDown}, "")

// This happens when users paste.
//
// Ref: https://github.com/walles/moar/issues/73
assertEncode(t, "1234", EventRune{rune: '1'}, "234")
}

func TestConsumeEncodedEventWithUnsupportedEscapeCode(t *testing.T) {
event, remainder := consumeEncodedEvent("\x1bXXXXX")
assert.Assert(t, event == nil)
assert.Equal(t, remainder, "")
}

func TestConsumeEncodedEventWithNoInput(t *testing.T) {
event, remainder := consumeEncodedEvent("")
assert.Assert(t, event == nil)
assert.Equal(t, remainder, "")
}

0 comments on commit 49f876b

Please sign in to comment.