Skip to content
Merged
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
Binary file added demo/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions demo/demo.tape
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# Run `demo/setup.sh` first; it never touches your real Root or History.
#
# demo/setup.sh && vhs demo/demo.tape
#
# Use VHS v0.11.0 (go install github.com/charmbracelet/vhs@v0.11.0).
# v0.12.0 cancels its own context before rendering and silently writes
# no GIF.

Output demo/demo.gif

Expand All @@ -13,11 +17,12 @@ Set Padding 20
Set Theme "Catppuccin Mocha"
Set TypingSpeed 60ms

Env XDG_CONFIG_HOME /tmp/cdd-demo/xdg/config
Env XDG_DATA_HOME /tmp/cdd-demo/xdg/data
Env XDG_CONFIG_HOME "/tmp/cdd-demo/xdg/config"
Env XDG_DATA_HOME "/tmp/cdd-demo/xdg/data"

Hide
Type "set -gx PATH /tmp/cdd-demo/bin $PATH" Enter
Type "set -g fish_autosuggestion_enabled 0" Enter
Type "cdd init fish | source" Enter
Type "cd /tmp/cdd-demo/root/lab/notes" Enter
Type "clear" Enter
Expand Down
2 changes: 1 addition & 1 deletion demo/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,6 @@ Try it in a shell:
export XDG_CONFIG_HOME=$CONFIG XDG_DATA_HOME=$DATA # bash/zsh
$BIN/cdd

Record it:
Record it (VHS v0.11.0; v0.12.0 silently writes no GIF):
vhs demo/demo.tape
MSG
14 changes: 12 additions & 2 deletions internal/picker/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (m Model) View() tea.View {
return tea.NewView("")
}
if len(m.rows) == 0 {
return tea.NewView(m.emptyHistoryView())
return fullScreen(m.emptyHistoryView())
}

t := newTheme(m.dark)
Expand Down Expand Up @@ -69,7 +69,17 @@ func (m Model) View() tea.View {
b.WriteString("\n")
b.WriteString(m.footerView(t, width, len(rows), lay))

return tea.NewView(b.String())
return fullScreen(b.String())
}

// fullScreen wraps content in a View drawn on the alternate screen. The
// frame always fills the terminal, and the alternate screen guarantees
// the shell's own scrollback comes back untouched when the Picker exits;
// inline rendering left stray lines above the prompt.
func fullScreen(content string) tea.View {
v := tea.NewView(content)
v.AltScreen = true
return v
}

// emptyHistoryView is shown when there are no rows at all: an empty
Expand Down
15 changes: 15 additions & 0 deletions internal/picker/view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,18 @@ func TestModel_View_FrameMatchesTerminalHeight(t *testing.T) {
}
}
}

// TestModel_View_UsesAlternateScreen pins the Picker to the alternate
// screen so nothing is left above the shell prompt after a Jump or cancel.
func TestModel_View_UsesAlternateScreen(t *testing.T) {
m := picker.NewModel(manyRows(3), noopStatus, picker.Options{})
next, _ := m.Update(tea.WindowSizeMsg{Width: 100, Height: 30})
m = next.(picker.Model)
if !m.View().AltScreen {
t.Errorf("View().AltScreen = false, want true")
}
empty := picker.NewModel(nil, noopStatus, picker.Options{})
if !empty.View().AltScreen {
t.Errorf("empty-History View().AltScreen = false, want true")
}
}