diff --git a/pkg/cy/cmd/module.go b/pkg/cy/cmd/module.go index 41291bc4..d8a530f6 100644 --- a/pkg/cy/cmd/module.go +++ b/pkg/cy/cmd/module.go @@ -5,7 +5,6 @@ import ( "github.com/cfoust/cy/pkg/bind" "github.com/cfoust/cy/pkg/geom" - "github.com/cfoust/cy/pkg/mux/screen" "github.com/cfoust/cy/pkg/mux/screen/replayable" "github.com/cfoust/cy/pkg/mux/stream" "github.com/cfoust/cy/pkg/sessions" @@ -39,10 +38,8 @@ func New( return nil, err } - terminal := screen.NewTerminal(ctx, recorder, geom.DEFAULT_SIZE) replayable := replayable.New( ctx, - terminal, cmd, recorder, replayBinds, diff --git a/pkg/emu/state.go b/pkg/emu/state.go index 96ba8604..452d304b 100644 --- a/pkg/emu/state.go +++ b/pkg/emu/state.go @@ -293,7 +293,7 @@ func (t *State) resize(cols, rows int) bool { t.clear(0, 0, cols-1, rows-1) } - if isAltMode(t.mode) { + if IsAltMode(t.mode) { history, lines, _, _ := reflow( altHistory, altLines, @@ -453,7 +453,7 @@ func between(val, min, max int) bool { return true } -func isAltMode(mode ModeFlag) bool { +func IsAltMode(mode ModeFlag) bool { return (mode & ModeAltScreen) != 0 } @@ -480,7 +480,7 @@ func (t *State) scrollDown(orig, n int) { } // don't save history lines on alt screen - if orig != 0 || isAltMode(t.mode) { + if orig != 0 || IsAltMode(t.mode) { return } @@ -502,7 +502,7 @@ func (t *State) scrollDown(orig, n int) { func (t *State) scrollUp(orig, n int) { n = clamp(n, 0, t.bottom-orig+1) - if orig == 0 && !isAltMode(t.mode) && !t.disableHistory { + if orig == 0 && !IsAltMode(t.mode) && !t.disableHistory { for i := 0; i < n; i++ { t.history = append(t.history, copyLine(t.lines[i])) } diff --git a/pkg/mux/screen/replayable/module.go b/pkg/mux/screen/replayable/module.go index 908e9563..08f06706 100644 --- a/pkg/mux/screen/replayable/module.go +++ b/pkg/mux/screen/replayable/module.go @@ -4,6 +4,7 @@ import ( "context" "github.com/cfoust/cy/pkg/bind" + "github.com/cfoust/cy/pkg/geom" "github.com/cfoust/cy/pkg/mux" S "github.com/cfoust/cy/pkg/mux/screen" "github.com/cfoust/cy/pkg/mux/screen/replay" @@ -19,7 +20,7 @@ type Replayable struct { util.Lifetime *S.Layers - screen mux.Screen + terminal *S.Terminal stream mux.Stream recorder *sessions.Recorder replay *taro.Program @@ -33,14 +34,28 @@ func (r *Replayable) Stream() mux.Stream { } func (r *Replayable) Screen() mux.Screen { - return r.screen + return r.terminal +} + +func (r *Replayable) Send(msg mux.Msg) { + // We want to automatically trigger replay mode when the user scrolls + // up with the mouse + if mouse, ok := msg.(taro.MouseMsg); ok { + isMouseUp := mouse.Type == taro.MousePress && mouse.Button == taro.MouseWheelUp + if isMouseUp && !r.terminal.IsAltMode() && r.Layers.NumLayers() == 1 { + r.EnterReplay() + return + } + } + + r.Layers.Send(msg) } func (r *Replayable) EnterReplay() { r.Lock() defer r.Unlock() - if r.NumLayers() > 1 { + if r.Layers.NumLayers() > 1 { return } @@ -51,7 +66,7 @@ func (r *Replayable) EnterReplay() { r.binds, ) - r.NewLayer( + r.Layers.NewLayer( replay.Ctx(), replay, S.PositionTop, @@ -64,7 +79,7 @@ func (r *Replayable) EnterReplay() { for { select { case event := <-events: - r.Publish(event) + r.Layers.Publish(event) case <-replay.Ctx().Done(): return } @@ -81,16 +96,16 @@ func (r *Replayable) EnterReplay() { func New( ctx context.Context, - screen mux.Screen, stream mux.Stream, recorder *sessions.Recorder, binds *bind.BindScope, ) *Replayable { lifetime := util.NewLifetime(ctx) + terminal := S.NewTerminal(lifetime.Ctx(), recorder, geom.DEFAULT_SIZE) layers := S.NewLayers() layers.NewLayer( lifetime.Ctx(), - screen, + terminal, S.PositionTop, S.WithInteractive, S.WithOpaque, @@ -99,7 +114,7 @@ func New( return &Replayable{ Lifetime: lifetime, binds: binds, - screen: screen, + terminal: terminal, stream: stream, recorder: recorder, Layers: layers, diff --git a/pkg/mux/screen/terminal.go b/pkg/mux/screen/terminal.go index 5828a770..deedcaa7 100644 --- a/pkg/mux/screen/terminal.go +++ b/pkg/mux/screen/terminal.go @@ -34,6 +34,10 @@ func (t *Terminal) Resize(size Size) error { return nil } +func (t *Terminal) IsAltMode() bool { + return emu.IsAltMode(t.terminal.Mode()) +} + func (t *Terminal) Send(msg mux.Msg) { input := make([]byte, 0) mode := t.terminal.Mode()