or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands.mdindex.mdinput.mdprogram.mdscreen.md

screen.mddocs/

0

# Terminal Control

1

2

Complete terminal and screen control functionality including alternate screen buffer, mouse modes, cursor control, focus reporting, and bracketed paste mode.

3

4

## Capabilities

5

6

### Screen Buffer Management

7

8

Control alternate screen buffer for full-screen terminal applications.

9

10

```go { .api }

11

/**

12

* ClearScreen clears the screen before next update

13

* Moves cursor to top-left and clears visual clutter

14

* Only needed for special cases, not regular redraws

15

* @returns Message to clear screen

16

*/

17

func ClearScreen() Msg

18

19

/**

20

* EnterAltScreen switches to alternate screen buffer

21

* Provides full-window mode, hiding terminal history

22

* Screen automatically restored on program exit

23

* @returns Message to enter alternate screen

24

*/

25

func EnterAltScreen() Msg

26

27

/**

28

* ExitAltScreen switches back to main screen buffer

29

* Returns to normal terminal with history visible

30

* Usually not needed as altscreen auto-exits on quit

31

* @returns Message to exit alternate screen

32

*/

33

func ExitAltScreen() Msg

34

```

35

36

**Usage Examples:**

37

38

```go

39

// Initialize with alternate screen

40

p := tea.NewProgram(model{}, tea.WithAltScreen())

41

42

// Or use commands for dynamic control

43

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

44

switch msg := msg.(type) {

45

case tea.KeyMsg:

46

switch msg.String() {

47

case "f":

48

return m, tea.EnterAltScreen()

49

case "ctrl+z":

50

// Clear screen before suspending

51

return m, tea.Batch(

52

tea.ClearScreen(),

53

tea.Suspend(),

54

)

55

}

56

}

57

return m, nil

58

}

59

```

60

61

### Mouse Control

62

63

Enable and configure mouse input modes.

64

65

```go { .api }

66

/**

67

* EnableMouseCellMotion enables mouse click, release, and wheel events

68

* Also captures mouse movement when button is pressed (drag events)

69

* Better terminal compatibility than all motion mode

70

* @returns Message to enable cell motion mouse mode

71

*/

72

func EnableMouseCellMotion() Msg

73

74

/**

75

* EnableMouseAllMotion enables all mouse events including hover

76

* Captures click, release, wheel, and motion without button press

77

* Less widely supported, use cell motion if unsure

78

* @returns Message to enable all motion mouse mode

79

*/

80

func EnableMouseAllMotion() Msg

81

82

/**

83

* DisableMouse stops listening for mouse events

84

* Mouse automatically disabled when program exits

85

* @returns Message to disable mouse input

86

*/

87

func DisableMouse() Msg

88

```

89

90

**Usage Examples:**

91

92

```go

93

// Static configuration (recommended)

94

p := tea.NewProgram(model{},

95

tea.WithMouseCellMotion(), // or WithMouseAllMotion()

96

)

97

98

// Dynamic mouse control

99

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

100

switch msg := msg.(type) {

101

case tea.KeyMsg:

102

switch msg.String() {

103

case "m":

104

if m.mouseEnabled {

105

m.mouseEnabled = false

106

return m, tea.DisableMouse()

107

} else {

108

m.mouseEnabled = true

109

return m, tea.EnableMouseCellMotion()

110

}

111

}

112

case tea.MouseMsg:

113

// Handle mouse events

114

return m.handleMouse(msg), nil

115

}

116

return m, nil

117

}

118

```

119

120

### Cursor Control

121

122

Show and hide the terminal cursor.

123

124

```go { .api }

125

/**

126

* HideCursor hides the terminal cursor

127

* Cursor automatically hidden during normal program lifetime

128

* Rarely needed unless terminal operations show cursor unexpectedly

129

* @returns Message to hide cursor

130

*/

131

func HideCursor() Msg

132

133

/**

134

* ShowCursor shows the terminal cursor

135

* Useful for input fields or when cursor should be visible

136

* @returns Message to show cursor

137

*/

138

func ShowCursor() Msg

139

```

140

141

**Usage Examples:**

142

143

```go

144

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

145

switch msg := msg.(type) {

146

case tea.KeyMsg:

147

switch msg.String() {

148

case "i":

149

// Enter input mode, show cursor

150

m.inputMode = true

151

return m, tea.ShowCursor()

152

case "esc":

153

// Exit input mode, hide cursor

154

m.inputMode = false

155

return m, tea.HideCursor()

156

}

157

}

158

return m, nil

159

}

160

```

161

162

### Bracketed Paste Control

163

164

Manage bracketed paste mode for handling large clipboard content.

165

166

```go { .api }

167

/**

168

* EnableBracketedPaste enables bracketed paste mode

169

* Large pastes delivered as single KeyMsg with Paste=true

170

* Bracketed paste enabled by default unless disabled via option

171

* @returns Message to enable bracketed paste

172

*/

173

func EnableBracketedPaste() Msg

174

175

/**

176

* DisableBracketedPaste disables bracketed paste mode

177

* Each character in paste delivered as separate KeyMsg

178

* @returns Message to disable bracketed paste

179

*/

180

func DisableBracketedPaste() Msg

181

```

182

183

**Usage Examples:**

184

185

```go

186

// Disable via program option

187

p := tea.NewProgram(model{}, tea.WithoutBracketedPaste())

188

189

// Dynamic control

190

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

191

switch msg := msg.(type) {

192

case tea.KeyMsg:

193

if msg.Paste {

194

// Handle large paste operation

195

m.content += string(msg.Runes)

196

return m, nil

197

}

198

// Handle regular keystrokes

199

return m.handleKey(msg), nil

200

}

201

return m, nil

202

}

203

```

204

205

### Focus Reporting

206

207

Enable terminal focus and blur event reporting.

208

209

```go { .api }

210

/**

211

* EnableReportFocus enables focus/blur event reporting

212

* Sends FocusMsg when terminal gains focus

213

* Sends BlurMsg when terminal loses focus

214

* @returns Message to enable focus reporting

215

*/

216

func EnableReportFocus() Msg

217

218

/**

219

* DisableReportFocus disables focus/blur event reporting

220

* @returns Message to disable focus reporting

221

*/

222

func DisableReportFocus() Msg

223

```

224

225

**Usage Examples:**

226

227

```go

228

// Enable via program option

229

p := tea.NewProgram(model{}, tea.WithReportFocus())

230

231

// Handle focus events

232

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

233

switch msg.(type) {

234

case tea.FocusMsg:

235

m.focused = true

236

// Maybe pause animations when not focused

237

return m, m.startAnimationCmd()

238

case tea.BlurMsg:

239

m.focused = false

240

// Pause updates when not focused

241

return m, nil

242

}

243

return m, nil

244

}

245

```

246

247

### Window Size Information

248

249

Handle terminal resize events and query current dimensions.

250

251

```go { .api }

252

/**

253

* WindowSizeMsg reports current terminal dimensions

254

* Automatically sent on program start and terminal resize

255

* Width and height in character cells (not pixels)

256

*/

257

type WindowSizeMsg struct {

258

Width int // Terminal width in characters

259

Height int // Terminal height in characters

260

}

261

```

262

263

**Usage Examples:**

264

265

```go

266

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

267

switch msg := msg.(type) {

268

case tea.WindowSizeMsg:

269

m.width = msg.Width

270

m.height = msg.Height

271

272

// Adjust layout based on size

273

if msg.Width < 80 {

274

m.layout = "compact"

275

} else {

276

m.layout = "full"

277

}

278

279

return m, nil

280

}

281

return m, nil

282

}

283

284

func (m model) View() string {

285

// Use m.width and m.height for responsive layout

286

content := m.renderContent()

287

288

// Ensure content fits terminal

289

if len(content) > m.height-1 {

290

content = content[:m.height-1]

291

}

292

293

return strings.Join(content, "\n")

294

}

295

```

296

297

## Deprecated Program Methods

298

299

These methods exist for backwards compatibility but should be avoided:

300

301

```go { .api }

302

/**

303

* Deprecated: Use WithAltScreen program option instead

304

* EnterAltScreen enters alternate screen if renderer is available

305

*/

306

func (p *Program) EnterAltScreen()

307

308

/**

309

* Deprecated: Altscreen automatically exits when program ends

310

* ExitAltScreen exits alternate screen if renderer is available

311

*/

312

func (p *Program) ExitAltScreen()

313

314

/**

315

* Deprecated: Use WithMouseCellMotion program option instead

316

* EnableMouseCellMotion enables mouse cell motion

317

*/

318

func (p *Program) EnableMouseCellMotion()

319

320

/**

321

* Deprecated: Mouse automatically disabled on program exit

322

* DisableMouseCellMotion disables mouse cell motion

323

*/

324

func (p *Program) DisableMouseCellMotion()

325

326

/**

327

* Deprecated: Use WithMouseAllMotion program option instead

328

* EnableMouseAllMotion enables mouse all motion

329

*/

330

func (p *Program) EnableMouseAllMotion()

331

332

/**

333

* Deprecated: Mouse automatically disabled on program exit

334

* DisableMouseAllMotion disables mouse all motion

335

*/

336

func (p *Program) DisableMouseAllMotion()

337

338

/**

339

* Deprecated: Use SetWindowTitle command instead

340

* SetWindowTitle sets window title if renderer is available

341

*/

342

func (p *Program) SetWindowTitle(title string)

343

```

344

345

## Terminal State Management Patterns

346

347

### Responsive Layout

348

349

Pattern for handling different terminal sizes:

350

351

```go

352

type layout struct {

353

compact bool

354

columns int

355

rows int

356

}

357

358

func (l layout) maxContentWidth() int {

359

if l.compact {

360

return l.columns - 2 // Leave margins

361

}

362

return min(l.columns-4, 120) // Max width for readability

363

}

364

365

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

366

switch msg := msg.(type) {

367

case tea.WindowSizeMsg:

368

m.layout = layout{

369

compact: msg.Width < 80,

370

columns: msg.Width,

371

rows: msg.Height,

372

}

373

return m, nil

374

}

375

return m, nil

376

}

377

378

func (m model) View() string {

379

maxWidth := m.layout.maxContentWidth()

380

content := wrapText(m.content, maxWidth)

381

382

if m.layout.compact {

383

return m.renderCompactView(content)

384

}

385

return m.renderFullView(content)

386

}

387

```

388

389

### Focus-Aware Updates

390

391

Pattern for pausing updates when terminal loses focus:

392

393

```go

394

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

395

switch msg.(type) {

396

case tea.FocusMsg:

397

m.focused = true

398

// Resume periodic updates

399

return m, m.startPeriodicUpdate()

400

401

case tea.BlurMsg:

402

m.focused = false

403

// Don't schedule more updates

404

return m, nil

405

406

case tickMsg:

407

if !m.focused {

408

// Skip update if not focused

409

return m, nil

410

}

411

// Normal update and reschedule

412

m.lastUpdate = time.Now()

413

return m, m.startPeriodicUpdate()

414

}

415

return m, nil

416

}

417

```

418

419

### Progressive Feature Detection

420

421

Pattern for enabling features based on terminal capabilities:

422

423

```go

424

func (m model) Init() tea.Cmd {

425

return tea.Batch(

426

tea.WindowSize(), // Get initial size

427

m.detectCapabilitiesCmd(),

428

)

429

}

430

431

type capabilitiesMsg struct {

432

hasMouseSupport bool

433

hasFocusReporting bool

434

hasAltScreen bool

435

}

436

437

func (m model) detectCapabilitiesCmd() tea.Cmd {

438

return func() tea.Msg {

439

// Simple capability detection

440

term := os.Getenv("TERM")

441

442

return capabilitiesMsg{

443

hasMouseSupport: term != "dumb",

444

hasFocusReporting: strings.Contains(term, "xterm"),

445

hasAltScreen: term != "dumb",

446

}

447

}

448

}

449

450

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

451

switch msg := msg.(type) {

452

case capabilitiesMsg:

453

var cmds []tea.Cmd

454

455

if msg.hasMouseSupport {

456

cmds = append(cmds, tea.EnableMouseCellMotion())

457

}

458

if msg.hasFocusReporting {

459

cmds = append(cmds, tea.EnableReportFocus())

460

}

461

if msg.hasAltScreen && m.wantsFullScreen {

462

cmds = append(cmds, tea.EnterAltScreen())

463

}

464

465

return m, tea.Batch(cmds...)

466

}

467

return m, nil

468

}

469

```