From 21881ab109f9259b567eb52ff0a0769efd8317a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:51:26 -0400 Subject: [PATCH 01/16] chore(deps): bump golangci/golangci-lint-action from 4 to 5 (#990) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 4 to 5. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v4...v5) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint-soft.yml | 2 +- .github/workflows/lint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-soft.yml b/.github/workflows/lint-soft.yml index a1eafa045f..9522e9d7fc 100644 --- a/.github/workflows/lint-soft.yml +++ b/.github/workflows/lint-soft.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v5 with: # Optional: golangci-lint command line arguments. args: --config .golangci-soft.yml --issues-exit-code=0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 881d0d3053..dddcf841fd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v5 with: # Optional: golangci-lint command line arguments. #args: From f946f1abb2bd7720e6f83b48e051783d84059542 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Thu, 2 May 2024 21:14:33 +0200 Subject: [PATCH 02/16] fix: support more shift and ctrl modifiers (#995) --- key_windows.go | 72 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/key_windows.go b/key_windows.go index c4b8aa75fb..f1ad2d3f90 100644 --- a/key_windows.go +++ b/key_windows.go @@ -170,29 +170,89 @@ func mouseEvent(p coninput.ButtonState, e coninput.MouseEventRecord) MouseMsg { func keyType(e coninput.KeyEventRecord) KeyType { code := e.VirtualKeyCode + shiftPressed := e.ControlKeyState.Contains(coninput.SHIFT_PRESSED) + ctrlPressed := e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED) + switch code { case coninput.VK_RETURN: return KeyEnter case coninput.VK_BACK: return KeyBackspace case coninput.VK_TAB: + if shiftPressed { + return KeyShiftTab + } return KeyTab case coninput.VK_SPACE: return KeyRunes // this could be KeySpace but on unix space also produces KeyRunes case coninput.VK_ESCAPE: return KeyEscape case coninput.VK_UP: - return KeyUp + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftUp + case shiftPressed: + return KeyShiftUp + case ctrlPressed: + return KeyCtrlUp + default: + return KeyUp + } case coninput.VK_DOWN: - return KeyDown + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftDown + case shiftPressed: + return KeyShiftDown + case ctrlPressed: + return KeyCtrlDown + default: + return KeyDown + } case coninput.VK_RIGHT: - return KeyRight + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftRight + case shiftPressed: + return KeyShiftRight + case ctrlPressed: + return KeyCtrlRight + default: + return KeyRight + } case coninput.VK_LEFT: - return KeyLeft + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftLeft + case shiftPressed: + return KeyShiftLeft + case ctrlPressed: + return KeyCtrlLeft + default: + return KeyLeft + } case coninput.VK_HOME: - return KeyHome + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftHome + case shiftPressed: + return KeyShiftHome + case ctrlPressed: + return KeyCtrlHome + default: + return KeyHome + } case coninput.VK_END: - return KeyEnd + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftEnd + case shiftPressed: + return KeyShiftEnd + case ctrlPressed: + return KeyCtrlEnd + default: + return KeyEnd + } case coninput.VK_PRIOR: return KeyPgUp case coninput.VK_NEXT: From 0c937f47b83acb05cec69cd6a2ff735809affdad Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Fri, 3 May 2024 09:23:29 -0300 Subject: [PATCH 03/16] fix: stop and drain timers (#993) Signed-off-by: Carlos Alexandro Becker --- commands.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/commands.go b/commands.go index 164dad21ad..2541bea0e4 100644 --- a/commands.go +++ b/commands.go @@ -94,11 +94,16 @@ type sequenceMsg []Cmd // // Every is analogous to Tick in the Elm Architecture. func Every(duration time.Duration, fn func(time.Time) Msg) Cmd { + n := time.Now() + d := n.Truncate(duration).Add(duration).Sub(n) + t := time.NewTimer(d) return func() Msg { - n := time.Now() - d := n.Truncate(duration).Add(duration).Sub(n) - t := time.NewTimer(d) - return fn(<-t.C) + ts := <-t.C + t.Stop() + for len(t.C) > 0 { + <-t.C + } + return fn(ts) } } @@ -141,9 +146,14 @@ func Every(duration time.Duration, fn func(time.Time) Msg) Cmd { // return m, nil // } func Tick(d time.Duration, fn func(time.Time) Msg) Cmd { + t := time.NewTimer(d) return func() Msg { - t := time.NewTimer(d) - return fn(<-t.C) + ts := <-t.C + t.Stop() + for len(t.C) > 0 { + <-t.C + } + return fn(ts) } } From 556cddecb043b8c0e7abee5608abbbf1b3bd3628 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Fri, 3 May 2024 13:54:50 -0400 Subject: [PATCH 04/16] chore(readme): add ntcharts to libs section --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 37499c186a..6957281b3e 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,7 @@ your program in another window. * [Lip Gloss][lipgloss]: Style, format and layout tools for terminal applications * [Harmonica][harmonica]: A spring animation library for smooth, natural motion * [BubbleZone][bubblezone]: Easy mouse event tracking for Bubble Tea components +* [ntcharts][ntcharts]: A terminal charting library built for Bubble Tea and [Lip Gloss][lipgloss] * [Termenv][termenv]: Advanced ANSI styling for terminal applications * [Reflow][reflow]: Advanced ANSI-aware methods for working with text @@ -316,6 +317,7 @@ your program in another window. [lipgloss]: https://github.com/charmbracelet/lipgloss [harmonica]: https://github.com/charmbracelet/harmonica [bubblezone]: https://github.com/lrstanley/bubblezone +[ntcharts]: https://github.com/NimbleMarkets/ntcharts [termenv]: https://github.com/muesli/termenv [reflow]: https://github.com/muesli/reflow From 7e05e1d009d07e6b7f0024ab60b1045b0fce7bbe Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 May 2024 11:28:34 -0400 Subject: [PATCH 05/16] fix(ci): remove deprecated 'ifshort' linter config --- .golangci-soft.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci-soft.yml b/.golangci-soft.yml index ef456e0605..1b6824bb2d 100644 --- a/.golangci-soft.yml +++ b/.golangci-soft.yml @@ -23,7 +23,6 @@ linters: - gomnd - gomoddirectives - goprintffuncname - - ifshort # - lll - misspell - nakedret From 3e129db31a9996d2621c4bbeeb1901c2e13df224 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 May 2024 11:36:18 -0400 Subject: [PATCH 06/16] chore(lint): add various nolint directives --- key.go | 2 +- mouse.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/key.go b/key.go index aac07d02fa..6ef0c54f9d 100644 --- a/key.go +++ b/key.go @@ -622,7 +622,7 @@ func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) { case '<': if matchIndices := mouseSGRRegex.FindSubmatchIndex(b[3:]); matchIndices != nil { // SGR mouse events length is the length of the match plus the length of the escape sequence - mouseEventSGRLen := matchIndices[1] + 3 + mouseEventSGRLen := matchIndices[1] + 3 //nolint:gomnd return mouseEventSGRLen, MouseMsg(parseSGRMouseEvent(b)) } } diff --git a/mouse.go b/mouse.go index add8d02931..6ec51cc0c0 100644 --- a/mouse.go +++ b/mouse.go @@ -45,7 +45,7 @@ func (m MouseEvent) String() (s string) { s += "shift+" } - if m.Button == MouseButtonNone { + if m.Button == MouseButtonNone { //nolint:nestif if m.Action == MouseActionMotion || m.Action == MouseActionRelease { s += mouseActions[m.Action] } else { @@ -172,7 +172,7 @@ const ( func parseSGRMouseEvent(buf []byte) MouseEvent { str := string(buf[3:]) matches := mouseSGRRegex.FindStringSubmatch(str) - if len(matches) != 5 { + if len(matches) != 5 { //nolint:gomnd // Unreachable, we already checked the regex in `detectOneMsg`. panic("invalid mouse event") } @@ -288,7 +288,7 @@ func parseMouseButton(b int, isSGR bool) MouseEvent { m.Type = MouseForward case m.Action == MouseActionMotion: m.Type = MouseMotion - switch m.Button { + switch m.Button { //nolint:exhaustive case MouseButtonLeft: m.Type = MouseLeft case MouseButtonMiddle: From e3c61538ee1196d80a0de61f7b56ca98cc69d6ea Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 May 2024 11:36:30 -0400 Subject: [PATCH 07/16] chore(lint): remove naked returns --- key.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/key.go b/key.go index 6ef0c54f9d..89a588aec0 100644 --- a/key.go +++ b/key.go @@ -632,7 +632,7 @@ func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) { var foundbp bool foundbp, w, msg = detectBracketedPaste(b) if foundbp { - return + return w, msg } // Detect escape sequence and control characters other than NUL, @@ -641,7 +641,7 @@ func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) { var foundSeq bool foundSeq, w, msg = detectSequence(b) if foundSeq { - return + return w, msg } // No non-NUL control character or escape sequence. From 601d2289c904e5b3f3ac34f728978252e9c8b0e8 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 8 May 2024 14:30:42 -0400 Subject: [PATCH 08/16] fix: renderer: reset the cursor on the first line We need to reset the cursor position on the first line before rendering. Otherwise, it might mess up the first line being rendered. Fixes: https://github.com/charmbracelet/bubbletea/issues/1000 Fixes: 46241068daed (feat: reduce console/term dependencies (#897)) --- screen_test.go | 18 +++++++++--------- standard_renderer.go | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/screen_test.go b/screen_test.go index 907a8d9a84..552b6f5c2b 100644 --- a/screen_test.go +++ b/screen_test.go @@ -14,47 +14,47 @@ func TestClearMsg(t *testing.T) { { name: "clear_screen", cmds: []Cmd{ClearScreen}, - expected: "\x1b[?25l\x1b[?2004h\x1b[2J\x1b[1;1H\x1b[1;1Hsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[2J\x1b[1;1H\x1b[1;1H\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "altscreen", cmds: []Cmd{EnterAltScreen, ExitAltScreen}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25l\x1b[?1049l\x1b[?25lsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25l\x1b[?1049l\x1b[?25l\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "altscreen_autoexit", cmds: []Cmd{EnterAltScreen}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25lsuccess\r\n\x1b[2;0H\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?1049l\x1b[?25h", + expected: "\x1b[?25l\x1b[?2004h\x1b[?1049h\x1b[2J\x1b[1;1H\x1b[1;1H\x1b[?25l\rsuccess\r\n\x1b[2;0H\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?1049l\x1b[?25h", }, { name: "mouse_cellmotion", cmds: []Cmd{EnableMouseCellMotion}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?1002h\x1b[?1006hsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?1002h\x1b[?1006h\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "mouse_allmotion", cmds: []Cmd{EnableMouseAllMotion}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?1003h\x1b[?1006hsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?1003h\x1b[?1006h\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "mouse_disable", cmds: []Cmd{EnableMouseAllMotion, DisableMouse}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?1003h\x1b[?1006h\x1b[?1002l\x1b[?1003l\x1b[?1006lsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?1003h\x1b[?1006h\x1b[?1002l\x1b[?1003l\x1b[?1006l\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "cursor_hide", cmds: []Cmd{HideCursor}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?25lsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?25l\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "cursor_hideshow", cmds: []Cmd{HideCursor, ShowCursor}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?25l\x1b[?25hsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?25l\x1b[?25h\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, { name: "bp_stop_start", cmds: []Cmd{DisableBracketedPaste, EnableBracketedPaste}, - expected: "\x1b[?25l\x1b[?2004h\x1b[?2004l\x1b[?2004hsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", + expected: "\x1b[?25l\x1b[?2004h\x1b[?2004l\x1b[?2004h\rsuccess\r\n\x1b[0D\x1b[2K\x1b[?2004l\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006l", }, } diff --git a/standard_renderer.go b/standard_renderer.go index 4e63fd6ecc..b2c2348328 100644 --- a/standard_renderer.go +++ b/standard_renderer.go @@ -232,6 +232,12 @@ func (r *standardRenderer) flush() { out.CursorDown(1) } } else { + if i == 0 && r.lastRender == "" { + // On first render, reset the cursor to the start of the line + // before writing anything. + buf.WriteByte('\r') + } + line := newLines[i] // Truncate lines wider than the width of the window to avoid From 8028edee96495fe5baef826c3b1b28627f7b49df Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 8 May 2024 15:01:53 -0400 Subject: [PATCH 09/16] fix: update examples testdata --- examples/simple/testdata/TestApp.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/testdata/TestApp.golden b/examples/simple/testdata/TestApp.golden index 52f68184c9..dbb51f684c 100644 --- a/examples/simple/testdata/TestApp.golden +++ b/examples/simple/testdata/TestApp.golden @@ -1,3 +1,3 @@ -[?25l[?2004hHi. This program will exit in 10 seconds. To quit sooner press any key +[?25l[?2004h Hi. This program will exit in 10 seconds. To quit sooner press any key Hi. This program will exit in 9 seconds. To quit sooner press any key. [?2004l[?25h[?1002l[?1003l[?1006l \ No newline at end of file From c31d33d8f23d371bbc326feff69b45a0035ab17e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 20:04:45 +0000 Subject: [PATCH 10/16] chore(deps): bump golang.org/x/sys from 0.19.0 to 0.20.0 Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.19.0 to 0.20.0. - [Commits](https://github.com/golang/sys/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 730e0ce70e..59ab106ab9 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/muesli/reflow v0.3.0 github.com/muesli/termenv v0.15.2 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 + golang.org/x/sys v0.20.0 golang.org/x/term v0.19.0 ) diff --git a/go.sum b/go.sum index afbec4daa8..19e2074e8d 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= From 4f070e4d6ff1f471294c308728b88fbaf2ecb81d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 20:04:31 +0000 Subject: [PATCH 11/16] chore(deps): bump golangci/golangci-lint-action from 5 to 6 Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 5 to 6. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v5...v6) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lint-soft.yml | 2 +- .github/workflows/lint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-soft.yml b/.github/workflows/lint-soft.yml index 9522e9d7fc..87d1e1f9b0 100644 --- a/.github/workflows/lint-soft.yml +++ b/.github/workflows/lint-soft.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v5 + uses: golangci/golangci-lint-action@v6 with: # Optional: golangci-lint command line arguments. args: --config .golangci-soft.yml --issues-exit-code=0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dddcf841fd..f617a5a281 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v5 + uses: golangci/golangci-lint-action@v6 with: # Optional: golangci-lint command line arguments. #args: From ea792a871f6c804ed30c3a68e57f913313c2262b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 20:08:46 +0000 Subject: [PATCH 12/16] chore(deps): bump golang.org/x/term from 0.19.0 to 0.20.0 Bumps [golang.org/x/term](https://github.com/golang/term) from 0.19.0 to 0.20.0. - [Commits](https://github.com/golang/term/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/term dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 59ab106ab9..40b1383211 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/muesli/termenv v0.15.2 golang.org/x/sync v0.7.0 golang.org/x/sys v0.20.0 - golang.org/x/term v0.19.0 + golang.org/x/term v0.20.0 ) require ( diff --git a/go.sum b/go.sum index 19e2074e8d..1f5eb9be44 100644 --- a/go.sum +++ b/go.sum @@ -29,7 +29,7 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= From cb36874306cff8e5d0dcd02b4983f755c19484f2 Mon Sep 17 00:00:00 2001 From: Louis Garman Date: Mon, 29 Apr 2024 18:31:15 +0100 Subject: [PATCH 13/16] docs: add pug to "in the wild" --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6957281b3e..1e14b5572e 100644 --- a/README.md +++ b/README.md @@ -387,6 +387,7 @@ For some Bubble Tea programs in production, see: * [portal](https://github.com/ZinoKader/portal): secure transfers between computers * [prs](https://github.com/dhth/prs): stay up to date with your PRs * [puffin](https://github.com/siddhantac/puffin): a TUI for hledger to manage your finances +* [pug](https://github.com/leg100/pug): terraform task manager * [punchout](https://github.com/dhth/punchout): takes the suck out of logging time on JIRA * [redis-viewer](https://github.com/SaltFishPr/redis-viewer): a Redis database browser * [redis_tui](https://github.com/mat2cc/redis_tui): a Redis database browser From ef4e46c488ede19715e6299eb3f66d7ec0e1af91 Mon Sep 17 00:00:00 2001 From: Night Cat <107802416+MHNightCat@users.noreply.github.com> Date: Thu, 9 May 2024 04:27:33 +0800 Subject: [PATCH 14/16] chore(readme): add superfile to 'in the wild' (#985) * docs: add superfile to "in the Wild" * Update README.md --------- Co-authored-by: Christian Rocha --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1e14b5572e..9a8d93e2a2 100644 --- a/README.md +++ b/README.md @@ -402,6 +402,7 @@ For some Bubble Tea programs in production, see: * [Storydb](https://github.com/grrlopes/storydb): an improved bash/zsh-style ctrl+r command history finder * [STTG](https://github.com/wille1101/sttg): a teletext client for SVT, Sweden’s national public television station * [sttr](https://github.com/abhimanyu003/sttr): a general-purpose text transformer +* [superfile](https://github.com/MHNightCat/superfile) a fancy, modern terminal-based file manager * [tasktimer](https://github.com/caarlos0/tasktimer): a dead-simple task timer * [termdbms](https://github.com/mathaou/termdbms): a keyboard and mouse driven database browser * [tgpt](https://github.com/aandrew-me/tgpt): conversational AI for the CLI; no API keys necessary From 920d07b07c187ede04272a2394ee53134163a5d6 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 16 May 2024 15:41:43 -0400 Subject: [PATCH 15/16] fix(windows): clean up windows input reader Remove unused and use CancelIo API to cancel reads. --- inputreader_windows.go | 51 ++---------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/inputreader_windows.go b/inputreader_windows.go index 5969721bc8..643529fc81 100644 --- a/inputreader_windows.go +++ b/inputreader_windows.go @@ -17,16 +17,9 @@ import ( type conInputReader struct { cancelMixin - conin windows.Handle - cancelEvent windows.Handle + conin windows.Handle originalMode uint32 - - // inputEvent holds the input event that was read in order to avoid - // unnecessary allocations. This re-use is possible because - // InputRecord.Unwarp which is called inparseInputMsgFromInputRecord - // returns an data structure that is independent of the passed InputRecord. - inputEvent []coninput.InputRecord } var _ cancelreader.CancelReader = &conInputReader{} @@ -53,14 +46,8 @@ func newInputReader(r io.Reader) (cancelreader.CancelReader, error) { return nil, fmt.Errorf("failed to prepare console input: %w", err) } - cancelEvent, err := windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return nil, fmt.Errorf("create stop event: %w", err) - } - return &conInputReader{ conin: conin, - cancelEvent: cancelEvent, originalMode: originalMode, }, nil } @@ -69,21 +56,11 @@ func newInputReader(r io.Reader) (cancelreader.CancelReader, error) { func (r *conInputReader) Cancel() bool { r.setCanceled() - err := windows.SetEvent(r.cancelEvent) - if err != nil { - return false - } - - return true + return windows.CancelIo(r.conin) == nil } // Close implements cancelreader.CancelReader. func (r *conInputReader) Close() error { - err := windows.CloseHandle(r.cancelEvent) - if err != nil { - return fmt.Errorf("closing cancel event handle: %w", err) - } - if r.originalMode != 0 { err := windows.SetConsoleMode(r.conin, r.originalMode) if err != nil { @@ -115,30 +92,6 @@ func prepareConsole(input windows.Handle, modes ...uint32) (originalMode uint32, return originalMode, nil } -func waitForInput(conin, cancel windows.Handle) error { - event, err := windows.WaitForMultipleObjects([]windows.Handle{conin, cancel}, false, windows.INFINITE) - switch { - case windows.WAIT_OBJECT_0 <= event && event < windows.WAIT_OBJECT_0+2: - if event == windows.WAIT_OBJECT_0+1 { - return cancelreader.ErrCanceled - } - - if event == windows.WAIT_OBJECT_0 { - return nil - } - - return fmt.Errorf("unexpected wait object is ready: %d", event-windows.WAIT_OBJECT_0) - case windows.WAIT_ABANDONED <= event && event < windows.WAIT_ABANDONED+2: - return fmt.Errorf("abandoned") - case event == uint32(windows.WAIT_TIMEOUT): - return fmt.Errorf("timeout") - case event == windows.WAIT_FAILED: - return fmt.Errorf("failed") - default: - return fmt.Errorf("unexpected error: %w", err) - } -} - // cancelMixin represents a goroutine-safe cancelation status. type cancelMixin struct { unsafeCanceled bool From 09f4ef0bc7864b6752e70306d5449efc3139b81a Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 16 May 2024 15:42:30 -0400 Subject: [PATCH 16/16] fix(windows): prevent firing multiple window size events On Windows, changing the alt-screen-buffer triggers a window-size-event. This might cause issues with some applications. Cache the last window-size-event and compare before sending it the model. Fixes: https://github.com/charmbracelet/bubbletea/issues/1019 --- key_windows.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/key_windows.go b/key_windows.go index f1ad2d3f90..a5dbfc832c 100644 --- a/key_windows.go +++ b/key_windows.go @@ -22,7 +22,8 @@ func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error { } func readConInputs(ctx context.Context, msgsch chan<- Msg, con windows.Handle) error { - var ps coninput.ButtonState // keep track of previous mouse state + var ps coninput.ButtonState // keep track of previous mouse state + var ws coninput.WindowBufferSizeEventRecord // keep track of the last window size event for { events, err := coninput.ReadNConsoleInputs(con, 16) if err != nil { @@ -45,10 +46,13 @@ func readConInputs(ctx context.Context, msgsch chan<- Msg, con windows.Handle) e }) } case coninput.WindowBufferSizeEventRecord: - msgs = append(msgs, WindowSizeMsg{ - Width: int(e.Size.X), - Height: int(e.Size.Y), - }) + if e != ws { + ws = e + msgs = append(msgs, WindowSizeMsg{ + Width: int(e.Size.X), + Height: int(e.Size.Y), + }) + } case coninput.MouseEventRecord: event := mouseEvent(ps, e) if event.Type != MouseUnknown {