or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands-groups.mdcontext-management.mdexception-handling.mdformatting.mdindex.mdparameter-types.mdparameters.mdterminal-ui.mdtesting-support.md

terminal-ui.mddocs/

0

# Terminal UI

1

2

Interactive CLI elements including prompts, confirmation dialogs, progress bars, styled output, and terminal utilities for building rich command-line experiences.

3

4

## Capabilities

5

6

### Output Functions

7

8

Core functions for displaying text and information to users.

9

10

```python { .api }

11

def echo(

12

message: object = None,

13

file: IO[str] | None = None,

14

nl: bool = True,

15

err: bool = False,

16

color: bool | None = None

17

) -> None:

18

"""

19

Print a message to stdout or stderr.

20

21

Parameters:

22

- message: Message to print (any object)

23

- file: File object to write to (defaults to stdout)

24

- nl: Add newline at end

25

- err: Write to stderr instead of stdout

26

- color: Enable/disable color output

27

28

Usage:

29

click.echo('Hello World')

30

click.echo('Error occurred', err=True)

31

click.echo('No newline', nl=False)

32

"""

33

34

def secho(

35

message: str | None = None,

36

file: IO[Any] | None = None,

37

nl: bool = True,

38

err: bool = False,

39

color: bool | None = None,

40

fg: str | None = None,

41

bg: str | None = None,

42

bold: bool | None = None,

43

dim: bool | None = None,

44

underline: bool | None = None,

45

blink: bool | None = None,

46

reverse: bool | None = None,

47

reset: bool = True,

48

) -> None:

49

"""

50

Print a styled message.

51

52

Parameters:

53

- message: Message to print

54

- file: File object to write to

55

- nl: Add newline at end

56

- err: Write to stderr instead of stdout

57

- color: Enable/disable color output

58

- fg: Foreground color ('red', 'green', 'blue', etc.)

59

- bg: Background color

60

- bold: Make text bold

61

- dim: Make text dim

62

- underline: Underline text

63

- blink: Make text blink

64

- reverse: Reverse colors

65

- reset: Reset styling after message

66

67

Usage:

68

click.secho('Success!', fg='green', bold=True)

69

click.secho('Warning', fg='yellow')

70

click.secho('Error', fg='red', err=True)

71

"""

72

```

73

74

### Text Styling

75

76

Functions for styling text with colors and formatting.

77

78

```python { .api }

79

def style(

80

text: str,

81

fg: str | None = None,

82

bg: str | None = None,

83

bold: bool | None = None,

84

dim: bool | None = None,

85

underline: bool | None = None,

86

blink: bool | None = None,

87

reverse: bool | None = None,

88

reset: bool = True,

89

) -> str:

90

"""

91

Style text with ANSI color codes.

92

93

Parameters:

94

- text: Text to style

95

- fg: Foreground color

96

- bg: Background color

97

- bold: Make text bold

98

- dim: Make text dim

99

- underline: Underline text

100

- blink: Make text blink

101

- reverse: Reverse colors

102

- reset: Reset styling after text

103

104

Returns:

105

Styled text string

106

107

Colors: black, red, green, yellow, blue, magenta, cyan, white, bright_black,

108

bright_red, bright_green, bright_yellow, bright_blue, bright_magenta,

109

bright_cyan, bright_white

110

111

Usage:

112

styled = click.style('Important', fg='red', bold=True)

113

click.echo(styled)

114

115

# Or use secho directly

116

click.secho('Important', fg='red', bold=True)

117

"""

118

119

def unstyle(text: str) -> str:

120

"""

121

Remove ANSI styling from text.

122

123

Parameters:

124

- text: Styled text

125

126

Returns:

127

Plain text without styling

128

129

Usage:

130

plain = click.unstyle('\x1b[31mRed Text\x1b[0m')

131

# plain == 'Red Text'

132

"""

133

```

134

135

### User Input

136

137

Functions for gathering input from users interactively.

138

139

```python { .api }

140

def prompt(

141

text: str,

142

default: str | None = None,

143

hide_input: bool = False,

144

confirmation_prompt: bool = False,

145

type: _ConvertibleType | None = None,

146

value_proc: Callable[[str | None], Any] | None = None,

147

prompt_suffix: str = ': ',

148

show_default: bool = True,

149

err: bool = False,

150

show_choices: bool = True,

151

) -> Any:

152

"""

153

Prompt user for input.

154

155

Parameters:

156

- text: Prompt text

157

- default: Default value if user presses enter

158

- hide_input: Hide input (for passwords)

159

- confirmation_prompt: Ask for confirmation (enter twice)

160

- type: Type for value conversion

161

- value_proc: Custom value processor

162

- prompt_suffix: Text after prompt

163

- show_default: Show default value in prompt

164

- err: Show prompt on stderr

165

- show_choices: Show choices for Choice type

166

167

Returns:

168

User input (converted to specified type)

169

170

Usage:

171

name = click.prompt('Your name')

172

age = click.prompt('Your age', type=int)

173

password = click.prompt('Password', hide_input=True)

174

email = click.prompt('Email', default='user@example.com')

175

"""

176

177

def confirm(

178

text: str,

179

default: bool = False,

180

abort: bool = False,

181

prompt_suffix: str = ' [y/N]: ',

182

show_default: bool = True,

183

err: bool = False,

184

) -> bool:

185

"""

186

Prompt for yes/no confirmation.

187

188

Parameters:

189

- text: Confirmation text

190

- default: Default choice (True for yes, False for no)

191

- abort: Abort if user chooses no

192

- prompt_suffix: Text after prompt

193

- show_default: Show default in prompt

194

- err: Show prompt on stderr

195

196

Returns:

197

True for yes, False for no

198

199

Usage:

200

if click.confirm('Delete all files?'):

201

delete_files()

202

203

# Abort if user says no

204

click.confirm('Continue?', abort=True)

205

"""

206

207

def getchar(echo: bool = False) -> str:

208

"""

209

Get a single character from input.

210

211

Parameters:

212

- echo: Echo the character

213

214

Returns:

215

Single character string

216

217

Usage:

218

click.echo('Press any key to continue...')

219

key = click.getchar()

220

click.echo(f'You pressed: {key}')

221

"""

222

```

223

224

### Progress Bars

225

226

Visual progress indicators for long-running operations.

227

228

```python { .api }

229

def progressbar(

230

iterable: Iterable | None = None,

231

length: int | None = None,

232

label: str | None = None,

233

show_eta: bool = True,

234

show_percent: bool | None = None,

235

show_pos: bool = False,

236

item_show_func: Callable[[Any], str] | None = None,

237

fill_char: str = '#',

238

empty_char: str = '-',

239

bar_template: str = '%(label)s [%(bar)s] %(info)s',

240

info_sep: str = ' ',

241

width: int = 36,

242

file: IO[Any] | None = None,

243

color: bool | None = None,

244

) -> ProgressBar:

245

"""

246

Create a progress bar context manager.

247

248

Parameters:

249

- iterable: Iterable to track progress for

250

- length: Total number of items (if iterable not provided)

251

- label: Progress bar label

252

- show_eta: Show estimated time remaining

253

- show_percent: Show percentage complete

254

- show_pos: Show current position

255

- item_show_func: Function to display current item

256

- fill_char: Character for completed portion

257

- empty_char: Character for remaining portion

258

- bar_template: Template for progress bar display

259

- info_sep: Separator for info sections

260

- width: Width of progress bar

261

- file: File to write to

262

- color: Enable colored progress bar

263

264

Returns:

265

ProgressBar context manager

266

267

Usage:

268

# With iterable

269

items = ['file1.txt', 'file2.txt', 'file3.txt']

270

with click.progressbar(items, label='Processing files') as bar:

271

for item in bar:

272

process_file(item)

273

274

# Manual progress

275

with click.progressbar(length=100, label='Training model') as bar:

276

for i in range(100):

277

train_step()

278

bar.update(1)

279

280

# Show current item

281

def show_item(item):

282

return f'Processing {item}'

283

284

with click.progressbar(files, item_show_func=show_item) as bar:

285

for file in bar:

286

process_file(file)

287

"""

288

```

289

290

### Internal Functions

291

292

Internal utility functions used by other terminal UI functions.

293

294

```python { .api }

295

def hidden_prompt_func(prompt: str) -> str:

296

"""

297

Internal function for password prompts.

298

299

Parameters:

300

- prompt: Prompt text to display

301

302

Returns:

303

Hidden input string

304

"""

305

306

def _build_prompt(

307

text: str,

308

suffix: str,

309

show_default: bool = True,

310

default: str | None = None

311

) -> str:

312

"""

313

Internal function to build prompt strings.

314

315

Parameters:

316

- text: Base prompt text

317

- suffix: Prompt suffix (e.g., ': ')

318

- show_default: Whether to show default value

319

- default: Default value

320

321

Returns:

322

Formatted prompt string

323

"""

324

```

325

326

### Terminal Utilities

327

328

Utility functions for terminal operations and information.

329

330

```python { .api }

331

def get_terminal_size() -> tuple[int, int]:

332

"""

333

Get terminal size.

334

335

Returns:

336

Tuple of (width, height) in characters

337

338

Usage:

339

width, height = click.get_terminal_size()

340

click.echo(f'Terminal: {width}x{height}')

341

"""

342

343

def clear() -> None:

344

"""

345

Clear the terminal screen.

346

347

Usage:

348

click.clear()

349

click.echo('Screen cleared!')

350

"""

351

352

def pause(info: str = 'Press any key to continue...', err: bool = False) -> None:

353

"""

354

Pause execution until user presses a key.

355

356

Parameters:

357

- info: Text to display

358

- err: Show message on stderr

359

360

Usage:

361

click.echo('Processing complete.')

362

click.pause()

363

"""

364

```

365

366

### File and Stream Utilities

367

368

Utility functions for file handling and stream operations.

369

370

```python { .api }

371

def get_binary_stream(name: str) -> IO[bytes]:

372

"""

373

Get a binary stream (stdin/stdout/stderr).

374

375

Parameters:

376

- name: Stream name ('stdin', 'stdout', 'stderr')

377

378

Returns:

379

Binary stream object

380

381

Usage:

382

stdout_binary = click.get_binary_stream('stdout')

383

stdout_binary.write(b'Binary data')

384

"""

385

386

def get_text_stream(name: str, encoding: str | None = None, errors: str = 'strict') -> IO[str]:

387

"""

388

Get a text stream (stdin/stdout/stderr).

389

390

Parameters:

391

- name: Stream name ('stdin', 'stdout', 'stderr')

392

- encoding: Text encoding (None for default)

393

- errors: Error handling strategy

394

395

Returns:

396

Text stream object

397

398

Usage:

399

stdout_text = click.get_text_stream('stdout', encoding='utf-8')

400

stdout_text.write('Text data')

401

"""

402

403

def open_file(

404

filename: str,

405

mode: str = 'r',

406

encoding: str | None = None,

407

errors: str = 'strict',

408

lazy: bool = False,

409

atomic: bool = False,

410

) -> Any:

411

"""

412

Open a file with enhanced features.

413

414

Parameters:

415

- filename: File path to open

416

- mode: File mode ('r', 'w', 'a', etc.)

417

- encoding: Text encoding

418

- errors: Error handling strategy

419

- lazy: Use lazy file opening

420

- atomic: Use atomic file operations

421

422

Returns:

423

File object (IO, LazyFile, or KeepOpenFile)

424

425

Usage:

426

# Regular file opening

427

with click.open_file('data.txt') as f:

428

content = f.read()

429

430

# Lazy file opening

431

lazy_file = click.open_file('large.txt', lazy=True)

432

433

# Atomic file operations

434

with click.open_file('config.json', 'w', atomic=True) as f:

435

json.dump(data, f)

436

"""

437

438

def format_filename(filename: str, shorten: bool = False) -> str:

439

"""

440

Format a filename for display.

441

442

Parameters:

443

- filename: File path to format

444

- shorten: Shorten long paths

445

446

Returns:

447

Formatted filename string

448

449

Usage:

450

display_name = click.format_filename('/very/long/path/to/file.txt', shorten=True)

451

click.echo(f'Processing: {display_name}')

452

"""

453

454

def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str:

455

"""

456

Get application data directory.

457

458

Parameters:

459

- app_name: Application name

460

- roaming: Use roaming profile on Windows

461

- force_posix: Force POSIX-style paths

462

463

Returns:

464

Application data directory path

465

466

Usage:

467

config_dir = click.get_app_dir('myapp')

468

config_file = os.path.join(config_dir, 'config.json')

469

"""

470

471

def get_os_args() -> list[str]:

472

"""

473

Get command line arguments from the OS.

474

475

Returns:

476

List of command line arguments

477

478

Usage:

479

args = click.get_os_args()

480

click.echo(f'Command line args: {args}')

481

"""

482

```

483

484

### Advanced File Classes

485

486

Special file classes for advanced file handling scenarios.

487

488

```python { .api }

489

class LazyFile:

490

name: str

491

mode: str

492

encoding: str | None

493

errors: str

494

atomic: bool

495

496

def __init__(

497

self,

498

filename: str,

499

mode: str = 'r',

500

encoding: str | None = None,

501

errors: str = 'strict',

502

atomic: bool = False,

503

) -> None:

504

"""

505

Lazy file that opens only when accessed.

506

507

Parameters:

508

- filename: File path

509

- mode: File mode

510

- encoding: Text encoding

511

- errors: Error handling strategy

512

- atomic: Use atomic operations

513

"""

514

515

def open(self) -> IO[Any]:

516

"""Open the file and return file object."""

517

518

def close(self) -> None:

519

"""Close the file if it's open."""

520

521

def close_intelligently(self) -> None:

522

"""Close file intelligently (don't close stdin/stdout/stderr)."""

523

524

def __enter__(self) -> LazyFile: ...

525

def __exit__(self, exctype, excinst, exctb) -> None: ...

526

def __iter__(self) -> Iterator[Any]: ...

527

528

class KeepOpenFile(Generic[AnyStr]):

529

def __init__(self, file: IO[AnyStr]) -> None:

530

"""

531

File wrapper that keeps file open.

532

533

Parameters:

534

- file: File object to wrap

535

"""

536

537

def __enter__(self) -> KeepOpenFile[AnyStr]: ...

538

def __exit__(self, exctype, excinst, exctb) -> None: ...

539

def __iter__(self) -> Iterator[AnyStr]: ...

540

```

541

542

### Utility Functions

543

544

Helper functions for various operations.

545

546

```python { .api }

547

def safecall(func: _T) -> _T:

548

"""

549

Safely call a function, handling exceptions.

550

551

Parameters:

552

- func: Function to call safely

553

554

Returns:

555

Function wrapper that handles exceptions

556

"""

557

558

def make_str(value: Any) -> str:

559

"""

560

Convert any value to string safely.

561

562

Parameters:

563

- value: Value to convert

564

565

Returns:

566

String representation of value

567

"""

568

569

def make_default_short_help(help: str, max_length: int = 45) -> str:

570

"""

571

Generate short help text from full help.

572

573

Parameters:

574

- help: Full help text

575

- max_length: Maximum length for short help

576

577

Returns:

578

Shortened help text

579

"""

580

```

581

582

### External Program Integration

583

584

Functions for launching external programs and editors.

585

586

```python { .api }

587

def edit(

588

text: str | None = None,

589

editor: str | None = None,

590

env: str | None = None,

591

require_save: bool = True,

592

extension: str = '.txt',

593

filename: str | None = None,

594

) -> str:

595

"""

596

Launch an editor to edit text.

597

598

Parameters:

599

- text: Initial text content

600

- editor: Editor command (uses $EDITOR if not specified)

601

- env: Environment variable for editor

602

- require_save: Require file to be saved

603

- extension: File extension for temporary file

604

- filename: Specific filename to use

605

606

Returns:

607

Edited text content

608

609

Usage:

610

# Edit empty text

611

content = click.edit()

612

613

# Edit existing content

614

config = load_config()

615

new_config = click.edit(config)

616

save_config(new_config)

617

618

# Use specific editor

619

text = click.edit(editor='nano')

620

"""

621

622

def launch(url: str, wait: bool = False, locate: bool = False) -> int:

623

"""

624

Launch a URL or file with the default application.

625

626

Parameters:

627

- url: URL or file path to launch

628

- wait: Wait for application to exit

629

- locate: Open file manager at location instead

630

631

Returns:

632

Exit code of launched application

633

634

Usage:

635

# Open URL in browser

636

click.launch('https://example.com')

637

638

# Open file with default application

639

click.launch('document.pdf')

640

641

# Open file manager at location

642

click.launch('/path/to/file', locate=True)

643

"""

644

```

645

646

### Paging

647

648

Display long text content with paging support.

649

650

```python { .api }

651

def echo_via_pager(

652

text_or_generator: str | Iterable[str] | Callable[[], Generator[str, None, None]],

653

color: bool | None = None

654

) -> None:

655

"""

656

Display text through a pager (less, more, etc.).

657

658

Parameters:

659

- text_or_generator: Text to display (string, iterable, or generator function)

660

- color: Enable colored output in pager

661

662

Usage:

663

# Page long text

664

long_text = generate_report()

665

click.echo_via_pager(long_text)

666

667

# Page generator output

668

def generate_lines():

669

for i in range(1000):

670

yield f'Line {i}\\n'

671

672

click.echo_via_pager(generate_lines)

673

674

# Page list of strings

675

lines = ['Line 1', 'Line 2', 'Line 3'] * 100

676

click.echo_via_pager(lines)

677

"""

678

```

679

680

### ProgressBar Class

681

682

Direct access to progress bar functionality.

683

684

```python { .api }

685

class ProgressBar:

686

length: int | None

687

label: str

688

689

def update(self, n_steps: int) -> None:

690

"""

691

Update progress by n steps.

692

693

Parameters:

694

- n_steps: Number of steps to advance

695

"""

696

697

def finish(self) -> None:

698

"""

699

Complete the progress bar.

700

"""

701

702

def __enter__(self) -> ProgressBar: ...

703

def __exit__(self, exc_type, exc_val, exc_tb) -> None: ...

704

def __iter__(self) -> ProgressBar: ...

705

def __next__(self) -> Any: ...

706

```