Skip to content

CodeEditor

Edit and highlight source code.

CodeEditor

Basic CodeEditor

Inherits: LayoutControl

Properties

Events

Methods

Usage#

Add flet-code-editor to your project dependencies:

uv add flet-code-editor
pip install flet-code-editor  # (1)!
  1. After this, you will have to manually add this package to your requirements.txt or pyproject.toml.

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(
        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)
"""


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",
        height=1.2,
    )

    gutter_style = fce.GutterStyle(
        text_style=ft.TextStyle(
            font_family="monospace",
            height=1.2,
        ),
        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.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,
                    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.Row(
            [
                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#

autocomplete class-attribute instance-attribute #

autocomplete: bool | None = False

Whether autocomplete is enabled.

autocomplete_words class-attribute instance-attribute #

autocomplete_words: list[str] | None = None

Words offered by autocomplete.

autofocus class-attribute instance-attribute #

autofocus: bool | None = False

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

code_theme class-attribute instance-attribute #

code_theme: CodeTheme | CustomCodeTheme | None = None

Syntax highlighting theme.

gutter_style class-attribute instance-attribute #

gutter_style: GutterStyle | None = None

Gutter styling.

language class-attribute instance-attribute #

language: CodeLanguage | None = None

Syntax highlighting language.

padding class-attribute instance-attribute #

padding: PaddingValue | None = None

Padding around the editor.

read_only class-attribute instance-attribute #

read_only: bool | None = False

Whether the editor is read-only.

selection class-attribute instance-attribute #

selection: TextSelection | None = 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_style class-attribute instance-attribute #

text_style: TextStyle | None = None

Text style for the editor content.

value class-attribute instance-attribute #

value: str | None = None

Full text including folded sections and service comments.

Events#

on_blur class-attribute instance-attribute #

on_blur: ControlEventHandler[CodeEditor] | None = None

Called when the editor loses focus.

on_change class-attribute instance-attribute #

on_change: ControlEventHandler[CodeEditor] | None = None

Called when the editor text changes.

on_focus class-attribute instance-attribute #

on_focus: ControlEventHandler[CodeEditor] | None = None

Called when the editor receives focus.

on_selection_change class-attribute instance-attribute #

on_selection_change: (
    EventHandler[TextSelectionChangeEvent[CodeEditor]]
    | None
) = None

Called when the text selection or caret position changes.

Methods#

focus async #

focus()

Request focus for this editor.

fold_at async #

fold_at(line_number: int)

Fold the block starting at the given line number.

fold_comment_at_line_zero async #

fold_comment_at_line_zero()

Fold the comment block at line 0.

fold_imports async #

fold_imports()

Fold import sections.