CodeEditor
Edit and highlight source code.

Inherits: LayoutControl
Properties
autocomplete- Whether autocomplete is enabled.autocomplete_words- Words offered by autocomplete.autofocus- Whether this editor should focus itself if nothing else is focused.code_theme- Syntax highlighting theme.gutter_style- Gutter styling.language- Syntax highlighting language.padding- Padding around the editor.read_only- Whether the editor is read-only.selection- Represents the current text selection or caret position in the editor.text_style- Text style for the editor content.value- Full text including folded sections and service comments.
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
focus- Request focus for this editor.fold_at- Fold the block starting at the given line number.fold_comment_at_line_zero- Fold the comment block at line 0.fold_imports- Fold import sections.
Usage
Add flet-code-editor to your project dependencies:
- uv
- pip
uv add flet-code-editor
pip install 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)

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)

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)

Properties
autocompleteclass-attributeinstance-attribute
autocomplete: Optional[bool] = FalseWhether autocomplete is enabled.
autocomplete_wordsclass-attributeinstance-attribute
autocomplete_words: Optional[list[str]] = NoneWords offered by autocomplete.
autofocusclass-attributeinstance-attribute
autofocus: Optional[bool] = FalseWhether this editor should focus itself if nothing else is focused.
code_themeclass-attributeinstance-attribute
code_theme: Optional[Union[CodeTheme, CustomCodeTheme]] = NoneSyntax highlighting theme.
gutter_styleclass-attributeinstance-attribute
gutter_style: Optional[GutterStyle] = NoneGutter styling.
languageclass-attributeinstance-attribute
language: Optional[CodeLanguage] = NoneSyntax highlighting language.
paddingclass-attributeinstance-attribute
padding: Optional[PaddingValue] = NonePadding around the editor.
read_onlyclass-attributeinstance-attribute
read_only: Optional[bool] = FalseWhether the editor is read-only.
selectionclass-attributeinstance-attribute
selection: Optional[TextSelection] = NoneRepresents 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] = NoneText style for the editor content.
valueclass-attributeinstance-attribute
value: Optional[str] = NoneFull text including folded sections and service comments.
Events
on_blurclass-attributeinstance-attribute
on_blur: Optional[ControlEventHandler[CodeEditor]] = NoneCalled when the editor loses focus.
on_changeclass-attributeinstance-attribute
on_change: Optional[ControlEventHandler[CodeEditor]] = NoneCalled when the editor text changes.
on_focusclass-attributeinstance-attribute
on_focus: Optional[ControlEventHandler[CodeEditor]] = NoneCalled when the editor receives focus.
on_selection_changeclass-attributeinstance-attribute
on_selection_change: Optional[EventHandler[TextSelectionChangeEvent[CodeEditor]]] = NoneCalled when the text selection or caret position changes.