From 250eb14de1954d62bd2d0426bc68a50128d27fa4 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 24 Aug 2024 10:35:59 +0200 Subject: [PATCH] Bump gocui --- go.mod | 2 +- go.sum | 4 +- .../github.com/jesseduffield/gocui/escape.go | 79 +++++++++++++------ vendor/github.com/jesseduffield/gocui/gui.go | 43 ++++++---- .../jesseduffield/gocui/tcell_driver.go | 3 + vendor/github.com/jesseduffield/gocui/view.go | 11 ++- vendor/modules.txt | 2 +- 7 files changed, 98 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index 59ea178ec..73a312f99 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/integrii/flaggy v1.4.0 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d - github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602 + github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9 github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e diff --git a/go.sum b/go.sum index 1605df605..caeb5acf7 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= -github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602 h1:nzGt/sRT0WCancALG5Q9e4DlQWGo7QUMc35rApdt+aM= -github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= +github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9 h1:1muwCO0cmCGHpOvNz1qTOrCFPECnBAV87yDE9Fgwy6U= +github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo= github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY= diff --git a/vendor/github.com/jesseduffield/gocui/escape.go b/vendor/github.com/jesseduffield/gocui/escape.go index b52c21495..f559bbb25 100644 --- a/vendor/github.com/jesseduffield/gocui/escape.go +++ b/vendor/github.com/jesseduffield/gocui/escape.go @@ -17,6 +17,7 @@ type escapeInterpreter struct { curFgColor, curBgColor Attribute mode OutputMode instruction instruction + hyperlink string } type ( @@ -40,7 +41,11 @@ const ( stateCSI stateParams stateOSC - stateOSCEscape + stateOSCWaitForParams + stateOSCParams + stateOSCHyperlink + stateOSCEndEscape + stateOSCSkipUnknown bold fontEffect = 1 faint fontEffect = 2 @@ -60,6 +65,7 @@ var ( errNotCSI = errors.New("Not a CSI escape sequence") errCSIParseError = errors.New("CSI escape sequence parsing error") errCSITooLong = errors.New("CSI escape sequence is too long") + errOSCParseError = errors.New("OSC escape sequence parsing error") ) // runes in case of error will output the non-parsed runes as a string. @@ -78,6 +84,7 @@ func (ei *escapeInterpreter) runes() []rune { ret = append(ret, ';') } return append(ret, ei.curch) + default: } return nil } @@ -191,15 +198,47 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) { return false, errCSIParseError } case stateOSC: - switch ch { - case 0x1b: - ei.state = stateOSCEscape + if ch == '8' { + ei.state = stateOSCWaitForParams + ei.hyperlink = "" return true, nil } + + ei.state = stateOSCSkipUnknown return true, nil - case stateOSCEscape: + case stateOSCWaitForParams: + if ch != ';' { + return true, errOSCParseError + } + + ei.state = stateOSCParams + return true, nil + case stateOSCParams: + if ch == ';' { + ei.state = stateOSCHyperlink + } + return true, nil + case stateOSCHyperlink: + switch ch { + case 0x07: + ei.state = stateNone + case 0x1b: + ei.state = stateOSCEndEscape + default: + ei.hyperlink += string(ch) + } + return true, nil + case stateOSCEndEscape: ei.state = stateNone return true, nil + case stateOSCSkipUnknown: + switch ch { + case 0x07: + ei.state = stateNone + case 0x1b: + ei.state = stateOSCEndEscape + } + return true, nil } return false, nil } @@ -267,58 +306,48 @@ func (ei *escapeInterpreter) outputCSI() error { func (ei *escapeInterpreter) csiColor(param []string) (color Attribute, skip int, err error) { if len(param) < 2 { - err = errCSIParseError - return + return 0, 0, errCSIParseError } switch param[1] { case "2": // 24-bit color if ei.mode < OutputTrue { - err = errCSIParseError - return + return 0, 0, errCSIParseError } if len(param) < 5 { - err = errCSIParseError - return + return 0, 0, errCSIParseError } var red, green, blue int red, err = strconv.Atoi(param[2]) if err != nil { - err = errCSIParseError - return + return 0, 0, errCSIParseError } green, err = strconv.Atoi(param[3]) if err != nil { - err = errCSIParseError - return + return 0, 0, errCSIParseError } blue, err = strconv.Atoi(param[4]) if err != nil { - err = errCSIParseError - return + return 0, 0, errCSIParseError } return NewRGBColor(int32(red), int32(green), int32(blue)), 5, nil case "5": // 8-bit color if ei.mode < Output256 { - err = errCSIParseError - return + return 0, 0, errCSIParseError } if len(param) < 3 { - err = errCSIParseError - return + return 0, 0, errCSIParseError } var hex int hex, err = strconv.Atoi(param[2]) if err != nil { - err = errCSIParseError - return + return 0, 0, errCSIParseError } return Get256Color(int32(hex)), 3, nil default: - err = errCSIParseError - return + return 0, 0, errCSIParseError } } diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index c1ee93ce4..9d848d93d 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -130,6 +130,7 @@ type Gui struct { managers []Manager keybindings []*keybinding focusHandler func(bool) error + openHyperlink func(string) error maxX, maxY int outputMode OutputMode stop chan struct{} @@ -624,6 +625,10 @@ func (g *Gui) SetFocusHandler(handler func(bool) error) { g.focusHandler = handler } +func (g *Gui) SetOpenHyperlinkFunc(openHyperlinkFunc func(string) error) { + g.openHyperlink = openHyperlinkFunc +} + // getKey takes an empty interface with a key and returns the corresponding // typed Key or rune. func getKey(key interface{}) (Key, rune, error) { @@ -1302,7 +1307,7 @@ func (g *Gui) onKey(ev *GocuiEvent) error { switch ev.Type { case eventKey: - _, err := g.execKeybindings(g.currentView, ev) + err := g.execKeybindings(g.currentView, ev) if err != nil { return err } @@ -1367,6 +1372,14 @@ func (g *Gui) onKey(ev *GocuiEvent) error { } } + if ev.Key == MouseLeft && !v.Editable && g.openHyperlink != nil { + if newY >= 0 && newY <= len(v.viewLines)-1 && newX >= 0 && newX <= len(v.viewLines[newY].line)-1 { + if link := v.viewLines[newY].line[newX].hyperlink; link != "" { + return g.openHyperlink(link) + } + } + } + if IsMouseKey(ev.Key) { opts := ViewMouseBindingOpts{X: newX, Y: newY} matched, err := g.execMouseKeybindings(v, ev, opts) @@ -1378,9 +1391,11 @@ func (g *Gui) onKey(ev *GocuiEvent) error { } } - if _, err := g.execKeybindings(v, ev); err != nil { + if err := g.execKeybindings(v, ev); err != nil { return err } + + default: } return nil @@ -1440,25 +1455,25 @@ func IsMouseScrollKey(key interface{}) bool { } // execKeybindings executes the keybinding handlers that match the passed view -// and event. The value of matched is true if there is a match and no errors. -func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) (matched bool, err error) { +// and event. +func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error { var globalKb *keybinding var matchingParentViewKb *keybinding // if we're searching, and we've hit n/N/Esc, we ignore the default keybinding if v != nil && v.IsSearching() && ev.Mod == ModNone { if eventMatchesKey(ev, g.NextSearchMatchKey) { - return true, v.gotoNextMatch() + return v.gotoNextMatch() } else if eventMatchesKey(ev, g.PrevSearchMatchKey) { - return true, v.gotoPreviousMatch() + return v.gotoPreviousMatch() } else if eventMatchesKey(ev, g.SearchEscapeKey) { v.searcher.clearSearch() if g.OnSearchEscape != nil { if err := g.OnSearchEscape(); err != nil { - return true, err + return err } } - return true, nil + return nil } } @@ -1486,26 +1501,26 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) (matched bool, err error) if g.currentView != nil && g.currentView.Editable && g.currentView.Editor != nil { matched := g.currentView.Editor.Edit(g.currentView, ev.Key, ev.Ch, ev.Mod) if matched { - return true, nil + return nil } } if globalKb != nil { return g.execKeybinding(v, globalKb) } - return false, nil + return nil } // execKeybinding executes a given keybinding -func (g *Gui) execKeybinding(v *View, kb *keybinding) (bool, error) { +func (g *Gui) execKeybinding(v *View, kb *keybinding) error { if g.isBlacklisted(kb.key) { - return true, nil + return nil } if err := kb.handler(g, v); err != nil { - return false, err + return err } - return true, nil + return nil } func (g *Gui) onFocus(ev *GocuiEvent) error { diff --git a/vendor/github.com/jesseduffield/gocui/tcell_driver.go b/vendor/github.com/jesseduffield/gocui/tcell_driver.go index 96f24390f..6665432c5 100644 --- a/vendor/github.com/jesseduffield/gocui/tcell_driver.go +++ b/vendor/github.com/jesseduffield/gocui/tcell_driver.go @@ -363,6 +363,7 @@ func (g *Gui) pollEvent() GocuiEvent { mouseKey = MouseRight case tcell.ButtonMiddle: mouseKey = MouseMiddle + default: } } @@ -374,11 +375,13 @@ func (g *Gui) pollEvent() GocuiEvent { dragState = NOT_DRAGGING case tcell.ButtonSecondary: case tcell.ButtonMiddle: + default: } mouseMod = Modifier(lastMouseMod) lastMouseMod = tcell.ModNone lastMouseKey = tcell.ButtonNone } + default: } if !wheeling { diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index e12991ee9..0752a5e9c 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -378,6 +378,7 @@ type viewLine struct { type cell struct { chr rune bgColor, fgColor Attribute + hyperlink string } type lineType []cell @@ -851,9 +852,10 @@ func (v *View) parseInput(ch rune, x int, _ int) (bool, []cell) { repeatCount = tabStop - (x % tabStop) } c := cell{ - fgColor: v.ei.curFgColor, - bgColor: v.ei.curBgColor, - chr: ch, + fgColor: v.ei.curFgColor, + bgColor: v.ei.curBgColor, + hyperlink: v.ei.hyperlink, + chr: ch, } for i := 0; i < repeatCount; i++ { cells = append(cells, c) @@ -1188,6 +1190,9 @@ func (v *View) draw() error { if bgColor == ColorDefault { bgColor = v.BgColor } + if c.hyperlink != "" { + fgColor |= AttrUnderline + } if err := v.setRune(x, y, c.chr, fgColor, bgColor); err != nil { return err diff --git a/vendor/modules.txt b/vendor/modules.txt index b271313d7..e1a96bb7b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem github.com/jesseduffield/go-git/v5/utils/merkletrie/index github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame github.com/jesseduffield/go-git/v5/utils/merkletrie/noder -# github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602 +# github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9 ## explicit; go 1.12 github.com/jesseduffield/gocui # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10