From 1a62c8bae5ed9c9cb9d87836a38030ef8e309edb Mon Sep 17 00:00:00 2001 From: "Christian G. Warden" Date: Fri, 8 Mar 2024 09:20:13 -0600 Subject: [PATCH] Lint Cleanup --- dom.go | 7 ++--- dom_test.go | 34 ++++++++++++------------ options.go | 31 ---------------------- standard_renderer.go | 63 +------------------------------------------- tea.go | 39 --------------------------- tea_test.go | 16 +++++------ 6 files changed, 28 insertions(+), 162 deletions(-) diff --git a/dom.go b/dom.go index 8dfe84a..79dde6a 100644 --- a/dom.go +++ b/dom.go @@ -1160,7 +1160,7 @@ func unmount(e ComponentOrHTML) { } // requestAnimationFrame calls the native JS function of the same name. -func requestAnimationFrame(callback func(float64, func(Msg)), send func(Msg)) int { +func requestAnimationFrame(callback func(float64, func(Msg)), send func(Msg)) { var cb jsFunc cb = funcOf(func(_ jsObject, args []jsObject) interface{} { cb.Release() @@ -1168,7 +1168,7 @@ func requestAnimationFrame(callback func(float64, func(Msg)), send func(Msg)) in callback(args[0].Float(), send) return undefined() }) - return global().Call("requestAnimationFrame", cb).Int() + global().Call("requestAnimationFrame", cb) } // RenderBody renders the given component as the document body. The given @@ -1191,9 +1191,6 @@ func RenderBody(body Component, send func(Msg)) { if err != nil { panic(err) } - if !isTest { - // select {} // run Go forever - } } // ElementMismatchError is returned when the element returned by a component diff --git a/dom_test.go b/dom_test.go index a005adf..197c59e 100644 --- a/dom_test.go +++ b/dom_test.go @@ -563,7 +563,7 @@ func TestRerender_identical(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -612,7 +612,7 @@ func TestRerender_identical(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCalled != 2 { @@ -652,7 +652,7 @@ func TestRerender_change(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -701,7 +701,7 @@ func TestRerender_change(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCalled != 2 { @@ -757,7 +757,7 @@ func TestRerender_Nested(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -805,7 +805,7 @@ func TestRerender_Nested(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if skipRenderCalled != 1 { @@ -857,7 +857,7 @@ func TestRerender_persistent(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -877,7 +877,7 @@ func TestRerender_persistent(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCount != 2 { @@ -888,7 +888,7 @@ func TestRerender_persistent(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCount != 3 { @@ -921,7 +921,7 @@ func TestRerender_persistent_direct(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -941,7 +941,7 @@ func TestRerender_persistent_direct(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCount != 2 { @@ -952,7 +952,7 @@ func TestRerender_persistent_direct(t *testing.T) { rerender(comp, send) // Invoke the render callback. - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) if renderCount != 3 { @@ -1049,7 +1049,7 @@ func TestRenderBody_Standard_loaded(t *testing.T) { defer ts.done() ts.strings.mock(`global.Get("document").Get("readyState")`, "loaded") - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -1068,7 +1068,7 @@ func TestRenderBody_Standard_loading(t *testing.T) { defer ts.done() ts.strings.mock(`global.Get("document").Get("readyState")`, "loading") - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -1089,7 +1089,7 @@ func TestRenderBody_Nested(t *testing.T) { defer ts.done() ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -1130,7 +1130,7 @@ func TestKeyedChild_DifferentType(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -1152,7 +1152,7 @@ func TestKeyedChild_DifferentType(t *testing.T) { rerender := func() { rerender(comp, send) - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.invokeCallbackRequestAnimationFrame(0) } diff --git a/options.go b/options.go index 2ef6a00..c8d815f 100644 --- a/options.go +++ b/options.go @@ -48,28 +48,6 @@ func WithoutSignals() ProgramOption { } } -// WithMouseCellMotion starts the program with the mouse enabled in "cell -// motion" mode. -// -// Cell motion mode enables mouse click, release, and wheel events. Mouse -// movement events are also captured if a mouse button is pressed (i.e., drag -// events). Cell motion mode is better supported than all motion mode. -// -// This will try to enable the mouse in extended mode (SGR), if that is not -// supported by the terminal it will fall back to normal mode (X10). -// -// To enable mouse cell motion once the program has already started running use -// the EnableMouseCellMotion command. To disable the mouse when the program is -// running use the DisableMouse command. -// -// The mouse will be automatically disabled when the program exits. -func WithMouseCellMotion() ProgramOption { - return func(p *Program) { - p.startupOptions |= withMouseCellMotion // set - p.startupOptions &^= withMouseAllMotion // clear - } -} - // WithoutRenderer disables the renderer. When this is set output and log // statements will be plainly sent to stdout (or another output if one is set) // without any rendering and redrawing logic. In other words, printing and @@ -118,12 +96,3 @@ func WithFilter(filter func(Model, Msg) Msg) ProgramOption { p.filter = filter } } - -// WithFPS sets a custom maximum FPS at which the renderer should run. If -// less than 1, the default value of 60 will be used. If over 120, the FPS -// will be capped at 120. -func WithFPS(fps int) ProgramOption { - return func(p *Program) { - p.fps = fps - } -} diff --git a/standard_renderer.go b/standard_renderer.go index 92e1ee2..273b406 100644 --- a/standard_renderer.go +++ b/standard_renderer.go @@ -1,53 +1,15 @@ package masc import ( - "bytes" "sync" - "time" ) -const ( - // defaultFramerate specifies the maximum interval at which we should - // update the view. - defaultFPS = 60 - maxFPS = 120 -) - -// standardRenderer is a framerate-based terminal renderer, updating the view -// at a given framerate to avoid overloading the terminal emulator. -// -// In cases where very high performance is needed the renderer can be told -// to exclude ranges of lines, allowing them to be written to directly. +// standardRenderer uses vecty's rendering model type standardRenderer struct { rootNode jsObject rendered bool mtx *sync.Mutex - - buf bytes.Buffer - queuedMessageLines []string - framerate time.Duration - ticker *time.Ticker - done chan struct{} - linesRendered int - useANSICompressor bool - once sync.Once - - // cursor visibility state - cursorHidden bool - - // essentially whether or not we're using the full size of the terminal - altScreenActive bool - - // whether or not we're currently using bracketed paste - bpActive bool - - // renderer dimensions; usually the size of the window - width int - height int - - // lines explicitly set not to render - ignoreLines map[int]struct{} } // newRenderer creates a new renderer. Normally you'll want to initialize it @@ -69,32 +31,9 @@ func newNodeRenderer(node jsObject) renderer { // start starts the renderer. func (r *standardRenderer) start() { - // Since the renderer can be restarted after a stop, we need to reset - // the done channel and its corresponding sync.Once. - r.once = sync.Once{} r.rendered = false } -// listen waits for ticks on the ticker, or a signal to stop the renderer. -func (r *standardRenderer) listen() { - for { - select { - case <-r.done: - r.ticker.Stop() - return - - case <-r.ticker.C: - r.flush() - } - } -} - -// flush renders the buffer. -func (r *standardRenderer) flush() { - r.mtx.Lock() - defer r.mtx.Unlock() -} - func isZeroValue(v jsObject) bool { return v == nil || !v.Truthy() } diff --git a/tea.go b/tea.go index 12dd6a5..c56f83c 100644 --- a/tea.go +++ b/tea.go @@ -12,7 +12,6 @@ import ( "runtime/debug" "sync" - "github.com/muesli/cancelreader" "golang.org/x/sync/errgroup" ) @@ -44,24 +43,6 @@ type Model interface { // update function. type Cmd func() Msg -type inputType int - -const ( - defaultInput inputType = iota - ttyInput - customInput -) - -// String implements the stringer interface for [inputType]. It is inteded to -// be used in testing. -func (i inputType) String() string { - return [...]string{ - "default input", - "tty input", - "custom input", - }[i] -} - // Options to customize the program during its initialization. These are // generally set with ProgramOptions. // @@ -117,8 +98,6 @@ type Program struct { // treated as bits. These options can be set via various ProgramOptions. startupOptions startupOptions - inputType inputType - ctx context.Context cancel context.CancelFunc @@ -128,17 +107,9 @@ type Program struct { renderer renderer - // where to read inputs from, this will usually be os.Stdin. - cancelReader cancelreader.CancelReader - readLoopDone chan struct{} - ignoreSignals uint32 filter func(Model, Msg) Msg - - // fps is the frames per second we should set on the renderer, if - // applicable, - fps int } // Quit is a special command that tells the Bubble Tea program to exit. @@ -173,13 +144,6 @@ func NewProgram(model Model, opts ...ProgramOption) *Program { return p } -// handleResize handles terminal resize events. -func (p *Program) handleResize() chan struct{} { - ch := make(chan struct{}) - - return ch -} - // handleCommands runs commands in a goroutine and sends the result to the // program's message channel. func (p *Program) handleCommands(cmds chan Cmd) chan struct{} { @@ -214,9 +178,6 @@ func (p *Program) handleCommands(cmds chan Cmd) chan struct{} { return ch } -func (p *Program) disableMouse() { -} - // eventLoop is the central message loop. It receives and handles the default // Bubble Tea messages, update the model and triggers redraws. func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) { diff --git a/tea_test.go b/tea_test.go index 727e4c5..3110d04 100644 --- a/tea_test.go +++ b/tea_test.go @@ -54,7 +54,7 @@ func TestTeaQuit(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -87,7 +87,7 @@ func testTeaWithFilter(t *testing.T, preventCount uint32) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -126,7 +126,7 @@ func TestTeaKill(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -155,7 +155,7 @@ func TestTeaContext(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -186,7 +186,7 @@ func TestTeaBatchMsg(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -224,7 +224,7 @@ func TestTeaSequenceMsg(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -254,7 +254,7 @@ func TestTeaSequenceMsgWithBatchMsg(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true) @@ -277,7 +277,7 @@ func TestTeaSend(t *testing.T) { ts := testSuite(t) defer ts.done() - ts.ints.mock(`global.Call("requestAnimationFrame", func)`, 0) + ts.isUndefined.mock(`global.Call("requestAnimationFrame", func)`, 0) ts.strings.mock(`global.Get("document").Get("readyState")`, "complete") ts.strings.mock(`global.Get("document").Call("querySelector", "body").Get("nodeName")`, "BODY") ts.truthies.mock(`global.Get("document").Call("querySelector", "body")`, true)