or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdcompletion.mdindex.mdkey-bindings.mdlayout.mdprompts.mdstyling.md

layout.mddocs/

0

# Layout and UI Components

1

2

Comprehensive layout system with containers, windows, controls, and widgets for building complex terminal interfaces. The layout system uses a hierarchical approach with containers that organize child components and controls that render actual content.

3

4

## Capabilities

5

6

### Layout Core

7

8

The Layout class serves as the root container for all UI components and manages focus and rendering.

9

10

```python { .api }

11

class Layout:

12

def __init__(self, container, focused_element=None):

13

"""

14

Create a layout with a root container.

15

16

Parameters:

17

- container: Root Container instance

18

- focused_element: Initial focused UI element

19

"""

20

21

def focus(self, focusable):

22

"""

23

Set focus to a specific UI element.

24

25

Parameters:

26

- focusable: UI element to focus

27

"""

28

29

def focus_next(self):

30

"""Move focus to next focusable element."""

31

32

def focus_previous(self):

33

"""Move focus to previous focusable element."""

34

35

def walk(container, skip_hidden=False):

36

"""

37

Walk through all UI elements in layout tree.

38

39

Parameters:

40

- container: Container to walk through

41

- skip_hidden: bool, whether to skip hidden elements

42

43

Yields:

44

UI elements in the container tree

45

"""

46

47

class InvalidLayoutError(Exception):

48

"""Exception raised for invalid layout configurations."""

49

```

50

51

### Dimensions

52

53

System for specifying layout dimensions with support for fixed, percentage, and weighted sizing.

54

55

```python { .api }

56

class Dimension:

57

def __init__(self, min=None, max=None, weight=None, preferred=None):

58

"""

59

Specify layout dimension constraints.

60

61

Parameters:

62

- min: int, minimum size

63

- max: int, maximum size

64

- weight: int, relative weight for distribution

65

- preferred: int, preferred size

66

"""

67

68

def D(min=None, max=None, weight=None, preferred=None):

69

"""

70

Shortcut function to create Dimension.

71

72

Parameters:

73

- min: int, minimum size

74

- max: int, maximum size

75

- weight: int, relative weight

76

- preferred: int, preferred size

77

78

Returns:

79

Dimension instance

80

"""

81

82

def sum_layout_dimensions(dimensions):

83

"""

84

Sum multiple dimensions.

85

86

Parameters:

87

- dimensions: List of Dimension instances

88

89

Returns:

90

Combined Dimension

91

"""

92

93

def max_layout_dimensions(dimensions):

94

"""

95

Get maximum of multiple dimensions.

96

97

Parameters:

98

- dimensions: List of Dimension instances

99

100

Returns:

101

Maximum Dimension

102

"""

103

104

def to_dimension(value):

105

"""

106

Convert value to Dimension.

107

108

Parameters:

109

- value: int, Dimension, or None

110

111

Returns:

112

Dimension instance

113

"""

114

115

def is_dimension(obj):

116

"""

117

Check if object is a Dimension.

118

119

Parameters:

120

- obj: Object to check

121

122

Returns:

123

bool: True if object is Dimension

124

"""

125

126

# Type alias for dimension values

127

AnyDimension = Union[None, int, Dimension]

128

```

129

130

### Container Classes

131

132

Container classes organize child UI elements with different layout strategies.

133

134

```python { .api }

135

class Container:

136

"""Abstract base class for all containers."""

137

138

def __init__(self):

139

"""Create base container."""

140

141

class HSplit(Container):

142

def __init__(

143

self,

144

children,

145

window_too_small=None,

146

align=HorizontalAlign.JUSTIFY,

147

padding=0,

148

padding_char=None,

149

padding_style="",

150

width=None,

151

height=None,

152

z_index=None,

153

modal=False,

154

key_bindings=None,

155

style=""

156

):

157

"""

158

Horizontal split container that stacks children vertically.

159

160

Parameters:

161

- children: List of child containers/windows

162

- window_too_small: Container to show when space is insufficient

163

- align: HorizontalAlign, horizontal alignment of children

164

- padding: int, padding around container

165

- padding_char: str, character for padding

166

- padding_style: str, style for padding

167

- width: AnyDimension, container width

168

- height: AnyDimension, container height

169

- z_index: int, z-order for overlapping

170

- modal: bool, whether container is modal

171

- key_bindings: KeyBindings for container

172

- style: str, CSS-like style

173

"""

174

175

class VSplit(Container):

176

def __init__(

177

self,

178

children,

179

window_too_small=None,

180

align=VerticalAlign.JUSTIFY,

181

padding=0,

182

padding_char=None,

183

padding_style="",

184

width=None,

185

height=None,

186

z_index=None,

187

modal=False,

188

key_bindings=None,

189

style=""

190

):

191

"""

192

Vertical split container that arranges children horizontally.

193

194

Parameters:

195

- children: List of child containers/windows

196

- window_too_small: Container to show when space is insufficient

197

- align: VerticalAlign, vertical alignment of children

198

- padding: int, padding around container

199

- padding_char: str, character for padding

200

- padding_style: str, style for padding

201

- width: AnyDimension, container width

202

- height: AnyDimension, container height

203

- z_index: int, z-order for overlapping

204

- modal: bool, whether container is modal

205

- key_bindings: KeyBindings for container

206

- style: str, CSS-like style

207

"""

208

209

class FloatContainer(Container):

210

def __init__(

211

self,

212

content,

213

floats=None,

214

modal=False,

215

key_bindings=None,

216

style=""

217

):

218

"""

219

Container with floating overlay elements.

220

221

Parameters:

222

- content: Background container content

223

- floats: List of Float instances for overlays

224

- modal: bool, whether container is modal

225

- key_bindings: KeyBindings for container

226

- style: str, CSS-like style

227

"""

228

229

class Float:

230

def __init__(

231

self,

232

content=None,

233

top=None,

234

right=None,

235

bottom=None,

236

left=None,

237

width=None,

238

height=None,

239

xcursor=False,

240

ycursor=False,

241

transparent=False,

242

allow_cover_cursor=False

243

):

244

"""

245

Floating element specification.

246

247

Parameters:

248

- content: Container content for float

249

- top: int, distance from top edge

250

- right: int, distance from right edge

251

- bottom: int, distance from bottom edge

252

- left: int, distance from left edge

253

- width: AnyDimension, float width

254

- height: AnyDimension, float height

255

- xcursor: bool, position relative to cursor X

256

- ycursor: bool, position relative to cursor Y

257

- transparent: bool, whether background is transparent

258

- allow_cover_cursor: bool, allow covering cursor

259

"""

260

261

class Window(Container):

262

def __init__(

263

self,

264

content=None,

265

width=None,

266

height=None,

267

z_index=None,

268

dont_extend_width=False,

269

dont_extend_height=False,

270

ignore_content_width=False,

271

ignore_content_height=False,

272

left_margins=None,

273

right_margins=None,

274

scroll_offsets=None,

275

allow_scroll_beyond_bottom=False,

276

wrap_lines=False,

277

get_vertical_scroll=None,

278

get_horizontal_scroll=None,

279

always_hide_cursor=False,

280

cursorline=False,

281

cursorcolumn=False,

282

colorcolumns=None,

283

align=WindowAlign.LEFT,

284

style="",

285

char=None

286

):

287

"""

288

Window container for displaying UI controls.

289

290

Parameters:

291

- content: UIControl instance to display

292

- width: AnyDimension, window width

293

- height: AnyDimension, window height

294

- z_index: int, z-order for overlapping

295

- dont_extend_width: bool, don't extend to fill width

296

- dont_extend_height: bool, don't extend to fill height

297

- ignore_content_width: bool, ignore content width

298

- ignore_content_height: bool, ignore content height

299

- left_margins: List of Margin instances for left side

300

- right_margins: List of Margin instances for right side

301

- scroll_offsets: ScrollOffsets for scrolling behavior

302

- allow_scroll_beyond_bottom: bool, allow scrolling past end

303

- wrap_lines: bool, wrap long lines

304

- get_vertical_scroll: Function returning vertical scroll position

305

- get_horizontal_scroll: Function returning horizontal scroll position

306

- always_hide_cursor: bool, never show cursor

307

- cursorline: bool, highlight cursor line

308

- cursorcolumn: bool, highlight cursor column

309

- colorcolumns: List of ColorColumn instances

310

- align: WindowAlign, content alignment

311

- style: str, CSS-like style

312

- char: str, background character

313

"""

314

315

class WindowRenderInfo:

316

"""Information about rendered window."""

317

def __init__(self):

318

"""Create window render info."""

319

320

class ConditionalContainer(Container):

321

def __init__(self, container, filter):

322

"""

323

Container shown based on condition.

324

325

Parameters:

326

- container: Container to wrap

327

- filter: Filter determining visibility

328

"""

329

330

class DynamicContainer(Container):

331

def __init__(self, get_container):

332

"""

333

Container with dynamic content.

334

335

Parameters:

336

- get_container: Function returning container

337

"""

338

339

class ScrollablePane(Container):

340

def __init__(

341

self,

342

content,

343

scroll_offsets=None,

344

keep_cursor_visible=True,

345

keep_focused_window_visible=True,

346

max_available_height=None,

347

width=None,

348

height=None,

349

show_scrollbar=True,

350

display_arrows=True,

351

up_arrow_symbol="^",

352

down_arrow_symbol="v"

353

):

354

"""

355

Scrollable container for content larger than display area.

356

357

Parameters:

358

- content: Container content to make scrollable

359

- scroll_offsets: ScrollOffsets configuration

360

- keep_cursor_visible: bool, ensure cursor stays visible

361

- keep_focused_window_visible: bool, keep focused window visible

362

- max_available_height: int, maximum height available

363

- width: AnyDimension, pane width

364

- height: AnyDimension, pane height

365

- show_scrollbar: bool, display scrollbar

366

- display_arrows: bool, show scroll arrows

367

- up_arrow_symbol: str, up arrow character

368

- down_arrow_symbol: str, down arrow character

369

"""

370

371

class ColorColumn:

372

def __init__(self, position, style="class:color-column"):

373

"""

374

Color column background marker.

375

376

Parameters:

377

- position: int, column position

378

- style: str, CSS-like style for column

379

"""

380

381

def to_container(container):

382

"""

383

Convert value to Container.

384

385

Parameters:

386

- container: Container, Window, or UIControl

387

388

Returns:

389

Container instance

390

"""

391

392

def to_window(container):

393

"""

394

Convert value to Window.

395

396

Parameters:

397

- container: Container, Window, or UIControl

398

399

Returns:

400

Window instance

401

"""

402

403

def is_container(obj):

404

"""

405

Check if object is a Container.

406

407

Parameters:

408

- obj: Object to check

409

410

Returns:

411

bool: True if object is Container

412

"""

413

414

# Type alias for container values

415

AnyContainer = Union[Container, UIControl]

416

```

417

418

### Alignment Enums

419

420

Enumeration classes for specifying alignment options.

421

422

```python { .api }

423

class HorizontalAlign(Enum):

424

"""Horizontal alignment options."""

425

LEFT = "left"

426

CENTER = "center"

427

RIGHT = "right"

428

JUSTIFY = "justify"

429

430

class VerticalAlign(Enum):

431

"""Vertical alignment options."""

432

TOP = "top"

433

CENTER = "center"

434

BOTTOM = "bottom"

435

JUSTIFY = "justify"

436

437

class WindowAlign(Enum):

438

"""Window content alignment options."""

439

LEFT = "left"

440

RIGHT = "right"

441

CENTER = "center"

442

```

443

444

### UI Controls

445

446

Controls are the components that actually render content within windows.

447

448

```python { .api }

449

class UIControl:

450

"""Abstract base class for UI controls."""

451

452

def create_content(self, width, height):

453

"""

454

Create content for rendering.

455

456

Parameters:

457

- width: int, available width

458

- height: int, available height

459

460

Returns:

461

UIContent instance

462

"""

463

464

class UIContent:

465

def __init__(

466

self,

467

get_line=None,

468

line_count=0,

469

cursor_position=None,

470

menu_position=None,

471

show_cursor=True

472

):

473

"""

474

UI content data for rendering.

475

476

Parameters:

477

- get_line: Function to get line content by index

478

- line_count: int, total number of lines

479

- cursor_position: Point, cursor position

480

- menu_position: Point, menu position

481

- show_cursor: bool, whether to show cursor

482

"""

483

484

class FormattedTextControl(UIControl):

485

def __init__(

486

self,

487

text="",

488

style="",

489

focusable=False,

490

key_bindings=None,

491

show_cursor=True

492

):

493

"""

494

Control for displaying formatted text.

495

496

Parameters:

497

- text: AnyFormattedText, text content to display

498

- style: str, CSS-like style

499

- focusable: bool, whether control can receive focus

500

- key_bindings: KeyBindings for control

501

- show_cursor: bool, whether to show cursor

502

"""

503

504

class BufferControl(UIControl):

505

def __init__(

506

self,

507

buffer=None,

508

lexer=None,

509

input_processors=None,

510

include_default_input_processors=True,

511

search_buffer_control=None,

512

menu_position=None,

513

focusable=True,

514

focus_on_click=False,

515

key_bindings=None,

516

get_cursor_position=None

517

):

518

"""

519

Control for displaying and editing buffer content.

520

521

Parameters:

522

- buffer: Buffer instance to display/edit

523

- lexer: Lexer for syntax highlighting

524

- input_processors: List of InputProcessor instances

525

- include_default_input_processors: bool, include default processors

526

- search_buffer_control: SearchBufferControl for search highlighting

527

- menu_position: Function returning menu position

528

- focusable: bool, whether control can receive focus

529

- focus_on_click: bool, focus on mouse click

530

- key_bindings: KeyBindings for control

531

- get_cursor_position: Function returning cursor position

532

"""

533

534

class SearchBufferControl(BufferControl):

535

def __init__(

536

self,

537

buffer=None,

538

input_processors=None,

539

lexer=None,

540

ignore_case=False

541

):

542

"""

543

Control for search buffer with highlighting.

544

545

Parameters:

546

- buffer: Buffer instance for search text

547

- input_processors: List of InputProcessor instances

548

- lexer: Lexer for syntax highlighting

549

- ignore_case: bool, case-insensitive search

550

"""

551

552

class DummyControl(UIControl):

553

def __init__(self):

554

"""Dummy control for testing and placeholders."""

555

```

556

557

### Scroll Configuration

558

559

Classes for configuring scrolling behavior.

560

561

```python { .api }

562

class ScrollOffsets:

563

def __init__(self, top=0, bottom=0, left=0, right=0):

564

"""

565

Scroll offset configuration.

566

567

Parameters:

568

- top: int, lines to keep visible above cursor

569

- bottom: int, lines to keep visible below cursor

570

- left: int, columns to keep visible left of cursor

571

- right: int, columns to keep visible right of cursor

572

"""

573

```

574

575

## Usage Examples

576

577

### Basic Layout Structure

578

579

```python

580

from prompt_toolkit.application import Application

581

from prompt_toolkit.layout import Layout

582

from prompt_toolkit.layout.containers import HSplit, VSplit, Window

583

from prompt_toolkit.layout.controls import FormattedTextControl

584

from prompt_toolkit.key_binding import KeyBindings

585

586

# Create layout with horizontal and vertical splits

587

layout = Layout(

588

HSplit([

589

# Header

590

Window(

591

FormattedTextControl('Header Area'),

592

height=1,

593

style='class:header'

594

),

595

# Main content area with sidebar

596

VSplit([

597

# Sidebar

598

Window(

599

FormattedTextControl('Sidebar'),

600

width=20,

601

style='class:sidebar'

602

),

603

# Main content

604

Window(FormattedTextControl('Main Content Area')),

605

]),

606

# Footer

607

Window(

608

FormattedTextControl('Footer Area'),

609

height=1,

610

style='class:footer'

611

)

612

])

613

)

614

615

# Key bindings

616

bindings = KeyBindings()

617

618

@bindings.add('c-c')

619

def exit_app(event):

620

event.app.exit()

621

622

# Create and run application

623

app = Application(

624

layout=layout,

625

key_bindings=bindings,

626

full_screen=True

627

)

628

629

app.run()

630

```

631

632

### Dynamic Layout with Conditions

633

634

```python

635

from prompt_toolkit.layout.containers import ConditionalContainer, HSplit, Window

636

from prompt_toolkit.layout.controls import FormattedTextControl

637

from prompt_toolkit.filters import Condition

638

639

# Create condition for showing/hiding sidebar

640

show_sidebar = Condition(lambda: True) # Can be dynamic

641

642

layout = Layout(

643

HSplit([

644

VSplit([

645

# Conditional sidebar

646

ConditionalContainer(

647

Window(

648

FormattedTextControl('Sidebar Content'),

649

width=20

650

),

651

filter=show_sidebar

652

),

653

# Main content

654

Window(FormattedTextControl('Main Content'))

655

])

656

])

657

)

658

```

659

660

### Floating Elements

661

662

```python

663

from prompt_toolkit.layout.containers import FloatContainer, Float, HSplit, Window

664

from prompt_toolkit.layout.controls import FormattedTextControl

665

666

# Create layout with floating dialog

667

layout = Layout(

668

FloatContainer(

669

# Background content

670

HSplit([

671

Window(FormattedTextControl('Background Content')),

672

]),

673

# Floating elements

674

floats=[

675

Float(

676

Window(

677

FormattedTextControl('Floating Dialog'),

678

width=40,

679

height=10

680

),

681

left=10,

682

top=5

683

)

684

]

685

)

686

)

687

```

688

689

### Scrollable Content

690

691

```python

692

from prompt_toolkit.layout.containers import ScrollablePane, HSplit, Window

693

from prompt_toolkit.layout.controls import FormattedTextControl

694

695

# Create large content that needs scrolling

696

large_content = '\n'.join([f'Line {i}' for i in range(100)])

697

698

layout = Layout(

699

ScrollablePane(

700

HSplit([

701

Window(FormattedTextControl(large_content))

702

]),

703

show_scrollbar=True

704

)

705

)

706

```

707

708

### Buffer Control with Editing

709

710

```python

711

from prompt_toolkit.buffer import Buffer

712

from prompt_toolkit.layout import Layout

713

from prompt_toolkit.layout.containers import HSplit, Window

714

from prompt_toolkit.layout.controls import BufferControl

715

from prompt_toolkit.lexers import PygmentsLexer

716

from pygments.lexers import PythonLexer

717

718

# Create buffer with Python content

719

buffer = Buffer(

720

document=Document('def hello():\n print("Hello, World!")'),

721

multiline=True

722

)

723

724

# Create buffer control with syntax highlighting

725

buffer_control = BufferControl(

726

buffer=buffer,

727

lexer=PygmentsLexer(PythonLexer)

728

)

729

730

layout = Layout(

731

HSplit([

732

Window(buffer_control),

733

Window(

734

FormattedTextControl('Press Ctrl-C to exit'),

735

height=1

736

)

737

])

738

)

739

```

740

741

### Margins and Decorations

742

743

```python

744

from prompt_toolkit.layout.margins import NumberedMargin, ScrollbarMargin

745

from prompt_toolkit.layout.containers import HSplit, Window

746

from prompt_toolkit.layout.controls import BufferControl

747

from prompt_toolkit.buffer import Buffer

748

749

# Create buffer

750

buffer = Buffer(multiline=True)

751

752

# Window with line numbers and scrollbar

753

layout = Layout(

754

HSplit([

755

Window(

756

BufferControl(buffer),

757

left_margins=[NumberedMargin()],

758

right_margins=[ScrollbarMargin()],

759

wrap_lines=True

760

)

761

])

762

)

763

```