Skip to main content

CodeEditor

Edit and highlight source code.

CodeEditor
Basic CodeEditor

Inherits: LayoutControl

Properties

Events

  • on_blur - Called when the editor loses focus.
  • on_change - Called when the editor text changes.
  • on_focus - Called when the editor receives focus.
  • on_selection_change - Called when the text selection or caret position changes.

Methods

Usage

Add flet-code-editor to your project dependencies:

uv add flet-code-editor

Examples

Basic example

import flet_code_editor as fce

import flet as ft

CODE = """import flet as ft

def main(page: ft.Page):
counter = ft.Text("0", size=50, data=0)

def btn_click(e):
counter.data += 1
counter.value = str(counter.data)
counter.update()

page.floating_action_button = ft.FloatingActionButton(
icon=ft.Icons.ADD, on_click=btn_click
)
page.add(
ft.SafeArea(
ft.Container(
counter,
alignment=ft.Alignment.CENTER,
expand=True,
),
expand=True,
),
)

ft.run(main)
"""


def main(page: ft.Page):
page.add(
ft.SafeArea(
expand=True,
content=fce.CodeEditor(
language=fce.CodeLanguage.PYTHON,
code_theme=fce.CodeTheme.ATOM_ONE_LIGHT,
value=CODE,
expand=True,
on_change=lambda e: print("Changed:", e.data),
),
)
)


if __name__ == "__main__":
ft.run(main)
code-editor-example-1

Selection handling

import flet_code_editor as fce

import flet as ft

CODE = """import flet as ft

def main(page: ft.Page):
counter = ft.Text("0", size=50, data=0)

def btn_click(e):
counter.data += 1
counter.value = str(counter.data)
counter.update()

page.floating_action_button = ft.FloatingActionButton(
icon=ft.Icons.ADD, on_click=btn_click
)
page.add(
ft.SafeArea(
ft.Container(
counter,
alignment=ft.Alignment.CENTER,
expand=True,
),
expand=True,
),
)

ft.run(main)
"""

font_families = [
# Apple platforms
"SF Mono",
"Menlo",
# Android
"Roboto Mono",
# Windows
"Consolas",
# Linux
"Ubuntu Mono",
# Universal fallbacks
"Courier New",
]


def main(page: ft.Page):
page.title = "CodeEditor selection"
max_selection_preview = 80

theme = fce.CustomCodeTheme(
keyword=ft.TextStyle(color=ft.Colors.INDIGO_600, weight=ft.FontWeight.W_600),
string=ft.TextStyle(color=ft.Colors.RED_700),
comment=ft.TextStyle(color=ft.Colors.GREY_600, italic=True),
)

text_style = ft.TextStyle(
font_family="monospace", font_family_fallback=font_families, size=12
)

gutter_style = fce.GutterStyle(
text_style=ft.TextStyle(
font_family="monospace", font_family_fallback=font_families, size=12
),
show_line_numbers=True,
show_folding_handles=True,
width=80,
)

def handle_selection_change(e: ft.TextSelectionChangeEvent[fce.CodeEditor]):
if e.selected_text:
normalized = " ".join(e.selected_text.split())
suffix = "..." if len(normalized) > max_selection_preview else ""
preview = normalized[:max_selection_preview]
selection.value = (
f"Selection ({len(e.selected_text)} chars): '{preview}{suffix}'"
)
else:
selection.value = "No selection."
selection_details.value = f"start={e.selection.start}, end={e.selection.end}"
caret.value = f"Caret position: {e.selection.end}"

async def select_all(e: ft.Event[ft.Button]):
await editor.focus()
editor.selection = ft.TextSelection(
base_offset=0,
extent_offset=len(editor.value or ""),
)

async def move_caret_to_start(e: ft.Event[ft.Button]):
await editor.focus()
editor.selection = ft.TextSelection(base_offset=0, extent_offset=0)

page.add(
ft.SafeArea(
expand=True,
content=ft.Column(
expand=True,
spacing=10,
controls=[
editor := fce.CodeEditor(
language=fce.CodeLanguage.PYTHON,
code_theme=theme,
autocomplete=True,
autocomplete_words=[
"Container",
"Button",
"Text",
"Row",
"Column",
],
value=CODE,
text_style=text_style,
gutter_style=gutter_style,
padding=10,
on_selection_change=handle_selection_change,
expand=True,
),
selection := ft.Text("Select some text from the editor."),
selection_details := ft.Text(),
caret := ft.Text("Caret position: -"),
ft.Row(
spacing=10,
controls=[
ft.Button("Select all text", on_click=select_all),
ft.Button(
"Move caret to start",
on_click=move_caret_to_start,
),
],
),
],
),
)
)


if __name__ == "__main__":
ft.run(main)
code-editor-example-2

Folding and initial selection

import flet_code_editor as fce

import flet as ft

CODE = """# 1
# 2
# 3
import json
import textwrap

print("Folding demo")
"""


def main(page: ft.Page):
editor = fce.CodeEditor(
language=fce.CodeLanguage.PYTHON,
value=CODE,
selection=ft.TextSelection(base_offset=41, extent_offset=62),
autofocus=True,
expand=True,
on_selection_change=lambda e: print("Selection:", e),
)

async def fold_imports():
await editor.fold_imports()

async def fold_comment():
await editor.fold_comment_at_line_zero()

page.add(
ft.SafeArea(
expand=True,
content=ft.Column(
controls=[
ft.Row(
controls=[
ft.Button("Fold imports", on_click=fold_imports),
ft.Button("Fold comment", on_click=fold_comment),
]
),
editor,
]
),
)
)


if __name__ == "__main__":
ft.run(main)
code-editor-example-3

Properties

autocompleteclass-attributeinstance-attribute

autocomplete: Optional[bool] = False

Whether autocomplete is enabled.

autocomplete_wordsclass-attributeinstance-attribute

autocomplete_words: Optional[list[str]] = None

Words offered by autocomplete.

autofocusclass-attributeinstance-attribute

autofocus: Optional[bool] = False

Whether this editor should focus itself if nothing else is focused.

code_themeclass-attributeinstance-attribute

code_theme: Optional[Union[CodeTheme, CustomCodeTheme]] = None

Syntax highlighting theme.

gutter_styleclass-attributeinstance-attribute

gutter_style: Optional[GutterStyle] = None

Gutter styling.

languageclass-attributeinstance-attribute

language: Optional[CodeLanguage] = None

Syntax highlighting language.

paddingclass-attributeinstance-attribute

padding: Optional[PaddingValue] = None

Padding around the editor.

read_onlyclass-attributeinstance-attribute

read_only: Optional[bool] = False

Whether the editor is read-only.

selectionclass-attributeinstance-attribute

selection: Optional[TextSelection] = None

Represents the current text selection or caret position in the editor.

Setting this property updates the editor selection and may trigger on_selection_change when the editor is focused.

text_styleclass-attributeinstance-attribute

text_style: Optional[TextStyle] = None

Text style for the editor content.

valueclass-attributeinstance-attribute

value: Optional[str] = None

Full text including folded sections and service comments.

Events

on_blurclass-attributeinstance-attribute

on_blur: Optional[ControlEventHandler[CodeEditor]] = None

Called when the editor loses focus.

on_changeclass-attributeinstance-attribute

on_change: Optional[ControlEventHandler[CodeEditor]] = None

Called when the editor text changes.

on_focusclass-attributeinstance-attribute

on_focus: Optional[ControlEventHandler[CodeEditor]] = None

Called when the editor receives focus.

on_selection_changeclass-attributeinstance-attribute

on_selection_change: Optional[EventHandler[TextSelectionChangeEvent[CodeEditor]]] = None

Called when the text selection or caret position changes.

Methods

focusasync

focus()

Request focus for this editor.

fold_atasync

fold_at(line_number: int)

Fold the block starting at the given line number.

fold_comment_at_line_zeroasync

fold_comment_at_line_zero()

Fold the comment block at line 0.

fold_importsasync

fold_imports()

Fold import sections.