or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

color-drawing.mdcontainer-widgets.mdcore-widgets.mddisplay-widgets.mdevent-system.mdfile-dialogs.mdindex.mdinput-widgets.mdlayouts.mdmodel-view.mdtext-editing.mdutilities.md

text-editing.mddocs/

0

# Text Editing

1

2

Multi-line text editing capabilities with syntax highlighting, line numbers, and advanced text manipulation features.

3

4

## Capabilities

5

6

### Text Edit Widget

7

8

TTkTextEdit provides comprehensive multi-line text editing functionality.

9

10

```python { .api }

11

class TTkTextEdit(TTkAbstractScrollArea):

12

def __init__(self, parent=None, **kwargs):

13

"""

14

Initialize a text edit widget.

15

16

Parameters:

17

- text (str): Initial text content

18

- readOnly (bool): Whether the editor is read-only

19

- lineWrapMode (int): Line wrapping mode

20

- wordWrapMode (int): Word wrapping mode

21

"""

22

23

def setText(self, text):

24

"""Set the text content."""

25

26

def text(self):

27

"""Get the text content."""

28

29

def append(self, text):

30

"""Append text to the end."""

31

32

def prepend(self, text):

33

"""Prepend text to the beginning."""

34

35

def insertText(self, text):

36

"""Insert text at cursor position."""

37

38

def clear(self):

39

"""Clear all text."""

40

41

def copy(self):

42

"""Copy selected text to clipboard."""

43

44

def cut(self):

45

"""Cut selected text to clipboard."""

46

47

def paste(self):

48

"""Paste text from clipboard."""

49

50

def undo(self):

51

"""Undo last operation."""

52

53

def redo(self):

54

"""Redo last undone operation."""

55

56

def selectAll(self):

57

"""Select all text."""

58

59

def setReadOnly(self, readOnly):

60

"""Set read-only mode."""

61

62

def isReadOnly(self):

63

"""Check if in read-only mode."""

64

65

def setLineWrapMode(self, mode):

66

"""Set line wrapping mode."""

67

68

def lineWrapMode(self):

69

"""Get line wrapping mode."""

70

71

def setWordWrapMode(self, mode):

72

"""Set word wrapping mode."""

73

74

def wordWrapMode(self):

75

"""Get word wrapping mode."""

76

77

def textCursor(self):

78

"""Get the text cursor."""

79

80

def setTextCursor(self, cursor):

81

"""Set the text cursor."""

82

83

def cursorPosition(self):

84

"""Get cursor position."""

85

86

def setCursorPosition(self, position):

87

"""Set cursor position."""

88

89

def hasSelectedText(self):

90

"""Check if text is selected."""

91

92

def selectedText(self):

93

"""Get selected text."""

94

95

def find(self, text, options=0):

96

"""Find text in the document."""

97

98

def replace(self, text):

99

"""Replace selected text."""

100

101

def setDocument(self, document):

102

"""Set the text document."""

103

104

def document(self):

105

"""Get the text document."""

106

107

def setTabStopWidth(self, width):

108

"""Set tab stop width."""

109

110

def tabStopWidth(self):

111

"""Get tab stop width."""

112

113

def isUndoRedoEnabled(self):

114

"""Check if undo/redo is enabled."""

115

116

def setUndoRedoEnabled(self, enabled):

117

"""Enable/disable undo/redo."""

118

119

# Signals

120

textChanged: pyTTkSignal # Emitted when text changes

121

cursorPositionChanged: pyTTkSignal # Emitted when cursor moves

122

selectionChanged: pyTTkSignal # Emitted when selection changes

123

undoAvailable: pyTTkSignal # Emitted when undo becomes available

124

redoAvailable: pyTTkSignal # Emitted when redo becomes available

125

```

126

127

### Text Edit View

128

129

TTkTextEditView provides the visual component of the text editor.

130

131

```python { .api }

132

class TTkTextEditView(TTkWidget):

133

def __init__(self, parent=None, **kwargs):

134

"""Initialize a text edit view."""

135

136

def setDocument(self, document):

137

"""Set the text document to display."""

138

139

def document(self):

140

"""Get the current document."""

141

142

def setTextCursor(self, cursor):

143

"""Set the text cursor."""

144

145

def textCursor(self):

146

"""Get the text cursor."""

147

148

def setLineNumberEnabled(self, enabled):

149

"""Enable/disable line numbers."""

150

151

def isLineNumberEnabled(self):

152

"""Check if line numbers are enabled."""

153

154

def setSyntaxHighlighter(self, highlighter):

155

"""Set syntax highlighter."""

156

157

def syntaxHighlighter(self):

158

"""Get syntax highlighter."""

159

```

160

161

### Text Edit Ruler

162

163

TTkTextEditRuler provides line numbers and editor annotations.

164

165

```python { .api }

166

class TTkTextEditRuler(TTkWidget):

167

def __init__(self, parent=None, **kwargs):

168

"""Initialize a text edit ruler."""

169

170

def setTextEdit(self, textEdit):

171

"""Set the associated text edit widget."""

172

173

def textEdit(self):

174

"""Get the associated text edit widget."""

175

176

def setLineNumbersVisible(self, visible):

177

"""Show/hide line numbers."""

178

179

def lineNumbersVisible(self):

180

"""Check if line numbers are visible."""

181

182

def setBookmarksEnabled(self, enabled):

183

"""Enable/disable bookmark support."""

184

185

def bookmarksEnabled(self):

186

"""Check if bookmarks are enabled."""

187

188

def addBookmark(self, line):

189

"""Add bookmark at line."""

190

191

def removeBookmark(self, line):

192

"""Remove bookmark from line."""

193

194

def hasBookmark(self, line):

195

"""Check if line has bookmark."""

196

197

def bookmarks(self):

198

"""Get list of bookmarked lines."""

199

```

200

201

### Text Cursor

202

203

TTkTextCursor provides navigation and text manipulation within documents.

204

205

```python { .api }

206

class TTkTextCursor:

207

def __init__(self, document=None):

208

"""

209

Initialize a text cursor.

210

211

Parameters:

212

- document: Text document to operate on

213

"""

214

215

def position(self):

216

"""Get cursor position."""

217

218

def setPosition(self, position, mode=None):

219

"""

220

Set cursor position.

221

222

Parameters:

223

- position (int): Character position

224

- mode: Selection mode (MoveAnchor, KeepAnchor)

225

"""

226

227

def movePosition(self, operation, mode=None, n=1):

228

"""

229

Move cursor by operation.

230

231

Parameters:

232

- operation: Move operation (Start, End, Up, Down, etc.)

233

- mode: Selection mode

234

- n: Number of operations

235

"""

236

237

def hasSelection(self):

238

"""Check if cursor has selection."""

239

240

def selectedText(self):

241

"""Get selected text."""

242

243

def selectionStart(self):

244

"""Get selection start position."""

245

246

def selectionEnd(self):

247

"""Get selection end position."""

248

249

def clearSelection(self):

250

"""Clear current selection."""

251

252

def select(self, selection):

253

"""Select text by selection type."""

254

255

def insertText(self, text):

256

"""Insert text at cursor position."""

257

258

def deleteChar(self):

259

"""Delete character at cursor."""

260

261

def deletePreviousChar(self):

262

"""Delete character before cursor."""

263

264

def beginEditBlock(self):

265

"""Begin an edit block for undo/redo."""

266

267

def endEditBlock(self):

268

"""End an edit block."""

269

270

def atStart(self):

271

"""Check if cursor is at document start."""

272

273

def atEnd(self):

274

"""Check if cursor is at document end."""

275

276

def atBlockStart(self):

277

"""Check if cursor is at block start."""

278

279

def atBlockEnd(self):

280

"""Check if cursor is at block end."""

281

```

282

283

### Text Document

284

285

TTkTextDocument represents the document model for text editing.

286

287

```python { .api }

288

class TTkTextDocument:

289

def __init__(self, parent=None):

290

"""Initialize a text document."""

291

292

def setPlainText(self, text):

293

"""Set document content as plain text."""

294

295

def toPlainText(self):

296

"""Get document content as plain text."""

297

298

def isEmpty(self):

299

"""Check if document is empty."""

300

301

def blockCount(self):

302

"""Get number of text blocks."""

303

304

def characterCount(self):

305

"""Get total character count."""

306

307

def lineCount(self):

308

"""Get number of lines."""

309

310

def findBlock(self, position):

311

"""Find text block at position."""

312

313

def findBlockByLineNumber(self, lineNumber):

314

"""Find text block by line number."""

315

316

def isModified(self):

317

"""Check if document is modified."""

318

319

def setModified(self, modified=True):

320

"""Set document modified state."""

321

322

def undo(self):

323

"""Undo last operation."""

324

325

def redo(self):

326

"""Redo last undone operation."""

327

328

def isUndoAvailable(self):

329

"""Check if undo is available."""

330

331

def isRedoAvailable(self):

332

"""Check if redo is available."""

333

334

def setUndoRedoEnabled(self, enabled):

335

"""Enable/disable undo/redo."""

336

337

def isUndoRedoEnabled(self):

338

"""Check if undo/redo is enabled."""

339

340

def clear(self):

341

"""Clear document content."""

342

343

# Signals

344

contentsChanged: pyTTkSignal # Emitted when content changes

345

modificationChanged: pyTTkSignal # Emitted when modification state changes

346

undoAvailable: pyTTkSignal # Emitted when undo availability changes

347

redoAvailable: pyTTkSignal # Emitted when redo availability changes

348

```

349

350

### Syntax Highlighting

351

352

TextDocumentHighlight provides syntax highlighting capabilities.

353

354

```python { .api }

355

class TextDocumentHighlight:

356

def __init__(self, parent=None):

357

"""Initialize syntax highlighter."""

358

359

def setDocument(self, document):

360

"""Set document to highlight."""

361

362

def document(self):

363

"""Get highlighted document."""

364

365

def highlightBlock(self, text):

366

"""Override to implement custom highlighting."""

367

368

def setFormat(self, start, count, format):

369

"""Set formatting for text range."""

370

371

def format(self, position):

372

"""Get format at position."""

373

374

def setDefaultColor(self, color):

375

"""Set default text color."""

376

377

def defaultColor(self):

378

"""Get default text color."""

379

380

def addKeyword(self, keyword, color):

381

"""Add keyword with color."""

382

383

def addPattern(self, pattern, color):

384

"""Add regex pattern with color."""

385

386

def setCommentColor(self, color):

387

"""Set comment color."""

388

389

def setStringColor(self, color):

390

"""Set string literal color."""

391

392

def setNumberColor(self, color):

393

"""Set number literal color."""

394

```

395

396

## Usage Examples

397

398

### Basic Text Editor

399

400

```python

401

import TermTk as ttk

402

403

root = ttk.TTk()

404

container = ttk.TTkContainer(parent=root)

405

layout = ttk.TTkVBoxLayout()

406

407

# Create text editor

408

text_edit = ttk.TTkTextEdit()

409

initial_text = """# Welcome to pyTermTk Text Editor

410

411

This is a multi-line text editor with the following features:

412

- Syntax highlighting

413

- Line numbers

414

- Undo/Redo support

415

- Find and replace

416

- Cut, copy, paste operations

417

418

Type your text here..."""

419

420

text_edit.setText(initial_text)

421

422

# Create toolbar

423

toolbar_layout = ttk.TTkHBoxLayout()

424

425

save_btn = ttk.TTkButton(text="Save")

426

load_btn = ttk.TTkButton(text="Load")

427

undo_btn = ttk.TTkButton(text="Undo")

428

redo_btn = ttk.TTkButton(text="Redo")

429

find_btn = ttk.TTkButton(text="Find")

430

431

toolbar_layout.addWidget(save_btn)

432

toolbar_layout.addWidget(load_btn)

433

toolbar_layout.addWidget(undo_btn)

434

toolbar_layout.addWidget(redo_btn)

435

toolbar_layout.addWidget(find_btn)

436

toolbar_layout.addStretch(1)

437

438

# Status bar

439

status = ttk.TTkLabel(text="Ready")

440

441

# Button handlers

442

@ttk.pyTTkSlot()

443

def save_file():

444

text = text_edit.text()

445

# Save logic here

446

status.setText("File saved")

447

448

@ttk.pyTTkSlot()

449

def undo_action():

450

text_edit.undo()

451

452

@ttk.pyTTkSlot()

453

def redo_action():

454

text_edit.redo()

455

456

# Connect buttons

457

save_btn.clicked.connect(save_file)

458

undo_btn.clicked.connect(undo_action)

459

redo_btn.clicked.connect(redo_action)

460

461

# Text change handler

462

@ttk.pyTTkSlot()

463

def text_changed():

464

status.setText("Modified")

465

466

text_edit.textChanged.connect(text_changed)

467

468

# Add to layout

469

layout.addLayout(toolbar_layout)

470

layout.addWidget(text_edit)

471

layout.addWidget(status)

472

473

container.setLayout(layout)

474

root.mainloop()

475

```

476

477

### Text Editor with Line Numbers

478

479

```python

480

import TermTk as ttk

481

482

root = ttk.TTk()

483

container = ttk.TTkContainer(parent=root)

484

layout = ttk.TTkHBoxLayout()

485

486

# Create text editor with ruler

487

text_edit = ttk.TTkTextEdit()

488

ruler = ttk.TTkTextEditRuler()

489

490

# Associate ruler with text editor

491

ruler.setTextEdit(text_edit)

492

ruler.setLineNumbersVisible(True)

493

ruler.setBookmarksEnabled(True)

494

495

# Sample code content

496

code_content = """#!/usr/bin/env python3

497

import TermTk as ttk

498

499

def main():

500

root = ttk.TTk()

501

502

# Create main window

503

window = ttk.TTkWindow(

504

parent=root,

505

title="My App",

506

size=(60, 20)

507

)

508

509

# Add widgets

510

label = ttk.TTkLabel(

511

parent=window,

512

text="Hello World!"

513

)

514

515

root.mainloop()

516

517

if __name__ == "__main__":

518

main()"""

519

520

text_edit.setText(code_content)

521

522

# Add bookmarks to some lines

523

ruler.addBookmark(1) # Bookmark shebang line

524

ruler.addBookmark(8) # Bookmark main window creation

525

526

layout.addWidget(ruler)

527

layout.addWidget(text_edit, stretch=1)

528

529

container.setLayout(layout)

530

root.mainloop()

531

```

532

533

### Find and Replace Dialog

534

535

```python

536

import TermTk as ttk

537

538

class FindReplaceDialog(ttk.TTkWindow):

539

def __init__(self, parent=None, text_edit=None):

540

super().__init__(parent=parent, title="Find & Replace", size=(40, 15))

541

self.text_edit = text_edit

542

543

layout = ttk.TTkVBoxLayout()

544

545

# Find section

546

find_layout = ttk.TTkHBoxLayout()

547

find_layout.addWidget(ttk.TTkLabel(text="Find:"))

548

self.find_edit = ttk.TTkLineEdit()

549

find_layout.addWidget(self.find_edit)

550

551

# Replace section

552

replace_layout = ttk.TTkHBoxLayout()

553

replace_layout.addWidget(ttk.TTkLabel(text="Replace:"))

554

self.replace_edit = ttk.TTkLineEdit()

555

replace_layout.addWidget(self.replace_edit)

556

557

# Options

558

self.case_sensitive = ttk.TTkCheckbox(text="Case sensitive")

559

self.whole_words = ttk.TTkCheckbox(text="Whole words only")

560

561

# Buttons

562

btn_layout = ttk.TTkHBoxLayout()

563

find_btn = ttk.TTkButton(text="Find Next")

564

replace_btn = ttk.TTkButton(text="Replace")

565

replace_all_btn = ttk.TTkButton(text="Replace All")

566

close_btn = ttk.TTkButton(text="Close")

567

568

btn_layout.addWidget(find_btn)

569

btn_layout.addWidget(replace_btn)

570

btn_layout.addWidget(replace_all_btn)

571

btn_layout.addWidget(close_btn)

572

573

# Add to layout

574

layout.addLayout(find_layout)

575

layout.addLayout(replace_layout)

576

layout.addWidget(self.case_sensitive)

577

layout.addWidget(self.whole_words)

578

layout.addLayout(btn_layout)

579

580

self.setLayout(layout)

581

582

# Connect buttons

583

find_btn.clicked.connect(self.find_next)

584

replace_btn.clicked.connect(self.replace_current)

585

replace_all_btn.clicked.connect(self.replace_all)

586

close_btn.clicked.connect(self.close)

587

588

@ttk.pyTTkSlot()

589

def find_next(self):

590

if self.text_edit:

591

find_text = self.find_edit.text()

592

options = 0

593

if self.case_sensitive.isChecked():

594

options |= ttk.TTkConstant.FindCaseSensitively

595

if self.whole_words.isChecked():

596

options |= ttk.TTkConstant.FindWholeWords

597

598

found = self.text_edit.find(find_text, options)

599

if not found:

600

print("Text not found")

601

602

@ttk.pyTTkSlot()

603

def replace_current(self):

604

if self.text_edit and self.text_edit.hasSelectedText():

605

replace_text = self.replace_edit.text()

606

self.text_edit.replace(replace_text)

607

608

@ttk.pyTTkSlot()

609

def replace_all(self):

610

if self.text_edit:

611

find_text = self.find_edit.text()

612

replace_text = self.replace_edit.text()

613

614

# Simple replace all implementation

615

content = self.text_edit.text()

616

if not self.case_sensitive.isChecked():

617

# Case insensitive replace

618

content = content.replace(find_text.lower(), replace_text)

619

else:

620

content = content.replace(find_text, replace_text)

621

622

self.text_edit.setText(content)

623

624

# Usage example

625

root = ttk.TTk()

626

container = ttk.TTkContainer(parent=root)

627

layout = ttk.TTkVBoxLayout()

628

629

text_edit = ttk.TTkTextEdit()

630

text_edit.setText("This is sample text. Find and replace this text.")

631

632

find_replace_btn = ttk.TTkButton(text="Find & Replace")

633

634

@ttk.pyTTkSlot()

635

def open_find_replace():

636

dialog = FindReplaceDialog(parent=root, text_edit=text_edit)

637

dialog.show()

638

639

find_replace_btn.clicked.connect(open_find_replace)

640

641

layout.addWidget(find_replace_btn)

642

layout.addWidget(text_edit)

643

644

container.setLayout(layout)

645

root.mainloop()

646

```

647

648

### Syntax Highlighted Code Editor

649

650

```python

651

import TermTk as ttk

652

653

class PythonSyntaxHighlighter(ttk.TextDocumentHighlight):

654

def __init__(self, parent=None):

655

super().__init__(parent=parent)

656

657

# Define colors

658

self.keyword_color = ttk.TTkColor(fg="#0066CC")

659

self.comment_color = ttk.TTkColor(fg="#008000")

660

self.string_color = ttk.TTkColor(fg="#AA0000")

661

self.number_color = ttk.TTkColor(fg="#FF6600")

662

663

# Python keywords

664

self.keywords = [

665

'def', 'class', 'import', 'from', 'if', 'else', 'elif',

666

'for', 'while', 'try', 'except', 'finally', 'with',

667

'return', 'yield', 'pass', 'break', 'continue',

668

'and', 'or', 'not', 'in', 'is', 'None', 'True', 'False'

669

]

670

671

def highlightBlock(self, text):

672

# Highlight keywords

673

for keyword in self.keywords:

674

index = text.find(keyword)

675

while index >= 0:

676

# Check if it's a whole word

677

if (index == 0 or not text[index-1].isalnum()) and \

678

(index + len(keyword) >= len(text) or not text[index + len(keyword)].isalnum()):

679

self.setFormat(index, len(keyword), self.keyword_color)

680

index = text.find(keyword, index + 1)

681

682

# Highlight comments

683

comment_index = text.find('#')

684

if comment_index >= 0:

685

self.setFormat(comment_index, len(text) - comment_index, self.comment_color)

686

687

# Highlight strings

688

for quote in ['"', "'"]:

689

start = 0

690

while True:

691

start = text.find(quote, start)

692

if start == -1:

693

break

694

end = text.find(quote, start + 1)

695

if end == -1:

696

end = len(text)

697

else:

698

end += 1

699

self.setFormat(start, end - start, self.string_color)

700

start = end

701

702

# Create code editor with syntax highlighting

703

root = ttk.TTk()

704

container = ttk.TTkContainer(parent=root)

705

706

text_edit = ttk.TTkTextEdit()

707

highlighter = PythonSyntaxHighlighter()

708

text_edit.setSyntaxHighlighter(highlighter)

709

710

sample_code = '''def factorial(n):

711

"""Calculate factorial of n"""

712

if n <= 1:

713

return 1

714

else:

715

return n * factorial(n - 1)

716

717

# Test the function

718

result = factorial(5)

719

print(f"Factorial of 5 is {result}")'''

720

721

text_edit.setText(sample_code)

722

723

container.addWidget(text_edit)

724

root.mainloop()

725

```