Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions clipboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@
}

//nolint:mnd
func handleClipboard(p *ansi.Parser) (string, error) {
func handleClipboard(p *ansi.Parser) (seqInfo, error) {
parts := bytes.Split(p.Data(), []byte{';'})
if len(parts) != 3 {
// Invalid, ignore
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}

if string(parts[2]) == "?" {
return fmt.Sprintf("Request %q clipboard", clipboardName[string(parts[1])]), nil
return seqNoMnemonic(fmt.Sprintf("Request %q clipboard", clipboardName[string(parts[1])])), nil
}

b64, err := base64.StdEncoding.DecodeString(string(parts[2]))
if err != nil {
// Invalid, ignore
//nolint:wrapcheck

Check failure on line 31 in clipboard.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (ubuntu-latest)

directive `//nolint:wrapcheck` is unused for linter "wrapcheck" (nolintlint)

Check failure on line 31 in clipboard.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (macos-latest)

directive `//nolint:wrapcheck` is unused for linter "wrapcheck" (nolintlint)

Check failure on line 31 in clipboard.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (windows-latest)

directive `//nolint:wrapcheck` is unused for linter "wrapcheck" (nolintlint)
return "", err
return seqNoMnemonic(""), err
}

return fmt.Sprintf("Set clipboard %q to %q", clipboardName[string(parts[1])], b64), nil
return seqNoMnemonic(fmt.Sprintf("Set clipboard %q to %q", clipboardName[string(parts[1])], b64)), nil
}
12 changes: 6 additions & 6 deletions color.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
)

//nolint:mnd
func handleTerminalColor(p *ansi.Parser) (string, error) {
func handleTerminalColor(p *ansi.Parser) (seqInfo, error) {
parts := bytes.Split(p.Data(), []byte{';'})
if len(parts) != 2 {
// Invalid, ignore
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}

arg := string(parts[1])
Expand All @@ -33,15 +33,15 @@ func handleTerminalColor(p *ansi.Parser) (string, error) {
if arg == "?" {
buf += " to " + arg
}
return buf, nil
return seqNoMnemonic(buf), nil
}

//nolint:mnd
func handleResetTerminalColor(p *ansi.Parser) (string, error) {
func handleResetTerminalColor(p *ansi.Parser) (seqInfo, error) {
parts := bytes.Split(p.Data(), []byte{';'})
if len(parts) != 1 {
// Invalid, ignore
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}
var buf string
switch p.Command() {
Expand All @@ -52,5 +52,5 @@ func handleResetTerminalColor(p *ansi.Parser) (string, error) {
case 112:
buf += "Reset cursor color"
}
return buf, nil
return seqNoMnemonic(buf), nil
}
57 changes: 42 additions & 15 deletions cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
)

//nolint:mnd
func handleCursor(p *ansi.Parser) (string, error) {
func handleCursor(p *ansi.Parser) (seqInfo, error) {
count := 1
if n, ok := p.Param(0, 1); ok && n > 0 {
count = n
Expand All @@ -18,20 +18,38 @@
switch cmd.Final() {
case 'A':
// CUU - Cursor Up
return fmt.Sprintf("Cursor up %d", default1(count)), nil
return seqInfo{
"CUU",
fmt.Sprintf("Cursor up %d", default1(count)),
}, nil
case 'B':
// CUD - Cursor Down
return fmt.Sprintf("Cursor down %d", default1(count)), nil
return seqInfo{
"CUD",
fmt.Sprintf("Cursor down %d", default1(count)),
}, nil
case 'C':
// CUF - Cursor Forward
return fmt.Sprintf("Cursor right %d", default1(count)), nil
return seqInfo{
"CUF",
fmt.Sprintf("Cursor right %d", default1(count)),
}, nil
case 'D':
// CUB - Cursor Back
return fmt.Sprintf("Cursor left %d", default1(count)), nil
return seqInfo{
"CUB",
fmt.Sprintf("Cursor left %d", default1(count)),
}, nil
case 'E':
return fmt.Sprintf("Cursor next line %d", default1(count)), nil
return seqInfo{
"CNL",
fmt.Sprintf("Cursor next line %d", default1(count)),
}, nil
case 'F':
return fmt.Sprintf("Cursor previous line %d", default1(count)), nil
return seqInfo{
"CPL",
fmt.Sprintf("Cursor previous line %d", default1(count)),
}, nil
case 'H':
row, col := 1, 1
if n, ok := p.Param(0, 1); ok && n > 0 {
Expand All @@ -40,23 +58,32 @@
if n, ok := p.Param(1, 1); ok && n > 0 {
col = n
}
return fmt.Sprintf("Set cursor position row=%[1]d col=%[2]d", row, col), nil
return seqInfo{
"CUP",
fmt.Sprintf("Set cursor position row=%[1]d col=%[2]d", row, col),
}, nil
case 'n':
if count != 6 {
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}
if isPrivate {
return "Request extended cursor position", nil
return seqInfo{
"DECXCPR",
"Request extended cursor position",
}, nil
}
return "Request cursor position", nil
return seqInfo{"CPR", "Request cursor position"}, nil
case 's':
return "Save cursor position", nil
return seqInfo{"SCOSC", "Save cursor position"}, nil
case 'u':
return "Restore cursor position", nil
return seqInfo{"SCORC", "Restore cursor position"}, nil
case 'q':
return fmt.Sprintf("Set cursor style %s", descCursorStyle(count)), nil
return seqInfo{
"DECSCUSR",
fmt.Sprintf("Set cursor style %s", descCursorStyle(count)),
}, nil
}
return "", errUnhandled
return seqNoMnemonic(""), errUnhandled
}

//nolint:mnd
Expand All @@ -75,6 +102,6 @@
case 6:
return "Steady bar"
default:
return "Unknown"

Check failure on line 105 in cursor.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (ubuntu-latest)

string `Unknown` has 3 occurrences, make it a constant (goconst)

Check failure on line 105 in cursor.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (macos-latest)

string `Unknown` has 3 occurrences, make it a constant (goconst)

Check failure on line 105 in cursor.go

View workflow job for this annotation

GitHub Actions / lint / lint-soft (windows-latest)

string `Unknown` has 3 occurrences, make it a constant (goconst)
}
}
8 changes: 4 additions & 4 deletions cwd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import (
)

//nolint:mnd
func handleWorkingDirectoryURL(p *ansi.Parser) (string, error) {
func handleWorkingDirectoryURL(p *ansi.Parser) (seqInfo, error) {
parts := bytes.Split(p.Data(), []byte{';'})
if len(parts) != 2 {
// Invalid, ignore
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}

u, err := url.ParseRequestURI(string(parts[1]))

if err != nil || u.Scheme != "file" {
// Should be a file URL.
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}

return fmt.Sprintf("Set working directory to %s (on %s)", u.Path, u.Host), nil
return seqNoMnemonic(fmt.Sprintf("Set working directory to %s (on %s)", u.Path, u.Host)), nil
}
26 changes: 17 additions & 9 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

import (
"errors"
"fmt"

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

var csiHandlers = map[int]handlerFn{
'm': handleSgr,
'c': printf("Request primary device attributes"),
'c': printWithMnemonic("DA1", "Request primary device attributes"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated but the description for DA1 should just be:

Suggested change
'c': printWithMnemonic("DA1", "Request primary device attributes"),
'c': printWithMnemonic("DA1", "Primary device attributes"),

When there is no parameters \x1b[c, it means a request for the terminal to send its primary device attributes which then responds with something like \x1b[64;1;2;3;4c, the same sequence command but with paramters.


// kitty
'u' | '?'<<markerShift: handleKitty,
Expand Down Expand Up @@ -73,24 +72,33 @@
}

var escHandler = map[int]handlerFn{
'7': printf("Save cursor"),
'8': printf("Restore cursor"),
'7': printWithMnemonic("DECSC", "Save cursor"),
'8': printWithMnemonic("DECRC", "Restore cursor"),

// C0/7-bit ASCII variant of ST.
// C1/8-bit extended ASCII variant handled as Ctrl.
'\\': printf("String terminator"),
'\\': printWithMnemonic("ST", "String terminator"),
}

var (
errUnhandled = errors.New("TODO: unhandled sequence")
errInvalid = errors.New("invalid sequence")
)

type handlerFn = func(*ansi.Parser) (string, error)
type seqInfo struct {
mnemonic string

Check failure on line 89 in handlers.go

View workflow job for this annotation

GitHub Actions / lint / lint (ubuntu-latest)

File is not properly formatted (gofumpt)
explanation string
}

func seqNoMnemonic(explanation string) seqInfo {
return seqInfo{"", explanation}
}

type handlerFn = func(*ansi.Parser) (seqInfo, error)

func printf(format string, v ...any) handlerFn { //nolint:unparam
return func(*ansi.Parser) (string, error) {
return fmt.Sprintf(format, v...), nil
func printWithMnemonic(mnemonic string, explanation string) handlerFn { //nolint:unparam
return func(*ansi.Parser) (seqInfo, error) {
return seqInfo{mnemonic, explanation}, nil
}
}

Expand Down
6 changes: 3 additions & 3 deletions hyperlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
)

//nolint:mnd
func handleHyperlink(p *ansi.Parser) (string, error) {
func handleHyperlink(p *ansi.Parser) (seqInfo, error) {
parts := bytes.Split(p.Data(), []byte{';'})
if len(parts) != 3 {
// Invalid, ignore
return "", errInvalid
return seqNoMnemonic(""), errInvalid
}

opts := bytes.Split(parts[1], []byte{':'})
Expand All @@ -25,5 +25,5 @@ func handleHyperlink(p *ansi.Parser) (string, error) {
}

buf += fmt.Sprintf(" to %q", parts[2])
return buf, nil
return seqNoMnemonic(buf), nil
}
14 changes: 7 additions & 7 deletions kitty.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

//nolint:mnd
func handleKitty(p *ansi.Parser) (string, error) {
func handleKitty(p *ansi.Parser) (seqInfo, error) {
flagDesc := func(flag int) string {
var r []string
if flag&1 != 0 {
Expand Down Expand Up @@ -49,18 +49,18 @@ func handleKitty(p *ansi.Parser) (string, error) {
cmd := ansi.Cmd(p.Command())
switch cmd.Prefix() {
case '?':
return "Request Kitty keyboard", nil
return seqNoMnemonic("Request Kitty keyboard"), nil
case '>':
if first == 0 {
return "Disable Kitty keyboard", nil
return seqNoMnemonic("Disable Kitty keyboard"), nil
}
return fmt.Sprintf("Push %q Kitty keyboard flag", flagDesc(first)), nil
return seqNoMnemonic(fmt.Sprintf("Push %q Kitty keyboard flag", flagDesc(first))), nil
case '<':
return fmt.Sprintf("Pop %d Kitty keyboard flags", first), nil
return seqNoMnemonic(fmt.Sprintf("Pop %d Kitty keyboard flags", first)), nil
case '=':
if n, ok := p.Param(1, 0); ok {
return fmt.Sprintf("Set %q Kitty keyboard flags to %q", flagDesc(first), modeDesc(n)), nil
return seqNoMnemonic(fmt.Sprintf("Set %q Kitty keyboard flags to %q", flagDesc(first), modeDesc(n))), nil
}
}
return "", errUnhandled
return seqNoMnemonic(""), errUnhandled
}
19 changes: 10 additions & 9 deletions line.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,31 @@ import (
)

//nolint:mnd
func handleLine(p *ansi.Parser) (string, error) {
func handleLine(p *ansi.Parser) (seqInfo, error) {
var count int
if n, ok := p.Param(0, 0); ok {
count = n
}

switch p.Command() {
case 'K':
mnemonic := "EL"
switch count {
case 0:
return "Erase line right", nil
return seqInfo{mnemonic, "Erase line right"}, nil
case 1:
return "Erase line left", nil
return seqInfo{mnemonic, "Erase line left"}, nil
case 2:
return "Erase entire line", nil
return seqInfo{mnemonic, "Erase entire line"}, nil
}
case 'L':
return fmt.Sprintf("Insert %d blank lines", default1(count)), nil
return seqInfo{"IL", fmt.Sprintf("Insert %d blank lines", default1(count))}, nil
case 'M':
return fmt.Sprintf("Delete %d lines", default1(count)), nil
return seqInfo{"DL", fmt.Sprintf("Delete %d lines", default1(count))}, nil
case 'S':
return fmt.Sprintf("Scroll up %d lines", default1(count)), nil
return seqInfo{"SU", fmt.Sprintf("Scroll up %d lines", default1(count))}, nil
case 'T':
return fmt.Sprintf("Scroll down %d lines", default1(count)), nil
return seqInfo{"SD", fmt.Sprintf("Scroll down %d lines", default1(count))}, nil
}
return "", errUnhandled
return seqNoMnemonic(""), errUnhandled
}
Loading
Loading