Skip to main content

fce-enhanced

PyPI version Python versions License CI Flet

An enhanced Flet CodeEditor control with file I/O, search/replace, syntax highlighting, and theme selection.

Built on top of flet-code-editor, adding a full-featured editing experience you can drop into any Flet app or run standalone. This project was created to explore and showcase what's possible with Flet — building a desktop-quality code editor entirely in Python.

fce-enhanced screenshot

Install

pip install fce-enhanced

Or with uv:

uv add fce-enhanced

Development setup

git clone https://github.com/oktl/flet-fce-enhanced.git
cd flet-fce-enhanced
uv sync
source .venv/bin/activate
pre-commit install  # optional, for development

Usage

Run as a standalone app

uvx fce-enhanced                     # open with an empty editor
uvx fce-enhanced path/to/file.py     # open a specific file on launch

During development:

flet run src/fce_enhanced/editor.py                     # open with an empty editor
flet run src/fce_enhanced/editor.py path/to/file.py     # open a specific file on launch

Embed in your own Flet app

EnhancedCodeEditor is a Flet declarative component (@ft.component). Render it with page.render(...) rather than page.add(...).

Minimal example

import flet as ft
from fce_enhanced import EnhancedCodeEditor


def main(page: ft.Page):
    page.title = "My Editor"
    page.render(lambda: EnhancedCodeEditor(expand=True))


ft.run(main)

With configuration

import flet as ft
import flet_code_editor as fce
from fce_enhanced import EnhancedCodeEditor


def main(page: ft.Page):
    page.title = "My Editor"

    def on_title_change(display_path, name, is_dirty):
        page.title = f"{name}{'*' if is_dirty else ''} — My Editor"

    page.render(
        lambda: EnhancedCodeEditor(
            language=fce.CodeLanguage.JAVASCRIPT,
            value="console.log('hello');",
            code_theme=fce.CodeTheme.MONOKAI,
            on_title_change=on_title_change,
            ruff_on_save=False,  # disable ruff (only applies to Python files)
            expand=True,
        )
    )


ft.run(main)

Driving the editor from code

Because a component has no instance to call methods on, pass an EditorHandle to drive it imperatively (open a file, save, etc.) and read its live state:

import sys
import flet as ft
from fce_enhanced import EditorHandle, EnhancedCodeEditor


def main(page: ft.Page):
    handle = EditorHandle()
    initial = sys.argv[1] if len(sys.argv) > 1 else None
    page.render(
        lambda: EnhancedCodeEditor(
            expand=True, handle=handle, initial_path=initial
        )
    )
    # handle.open_path("/path/to/file"), handle.save(), handle.save_as(),
    # handle.close(); read handle.value / handle.dirty / handle.current_path

ft.run(main)

initial_path opens a file automatically on mount — the simplest way to load a file at startup without touching the handle.

save_path is the opposite: it seeds the save target without reading from disk, so the content you pass in value stays on screen and Save writes to a path that need not exist yet. Use it when the buffer comes from somewhere other than the filesystem.

Constructor parameters

Parameter Type Default Description
language CodeLanguage PLAINTEXT Initial syntax highlighting language
value str "# New file\n" Initial editor content
show_toolbar bool True Show the file I/O toolbar
show_status_bar bool True Show the line/column status bar
show_gutter bool True Show the line-number gutter
register_keyboard_shortcuts bool True Register global keyboard shortcuts
autocomplete bool True Enable autocomplete
autocomplete_words list[str] None Custom autocomplete suggestions
code_theme CodeTheme ATOM_ONE_DARK Syntax highlighting theme
text_style TextStyle None Text style for editor content
gutter_style GutterStyle None Style for the line number gutter
on_title_change callable None Callback (display_path, name, is_dirty) — fires on file open/close, save, and dirty-state changes. display_path is the home-relative path (e.g. ~/projects/foo.py) or "untitled".
ruff_on_save bool False Auto-format Python files with ruff on save
initial_path str None File to open automatically on mount
save_path str None Save target seeded on mount without reading from disk (keeps value); ignored when initial_path is set
handle EditorHandle None Imperative handle for driving the editor
expand bool False Expand the root column to fill its parent

Driving via EditorHandle

Pass an EditorHandle instance and the component populates it on every render:

handle.open_path("/path/to/file")  # load a file (no dialog)
handle.save()                      # save to current path
handle.save_as()                   # save-as dialog
handle.close()                     # close current file
handle.revert()                    # revert to last saved content (confirms)

handle.open_search(with_replace=True)  # open the find/replace bar
handle.close_search()
handle.goto_line()                 # go-to-line dialog
handle.command_palette()           # command palette
handle.show_help()                 # help dialog

handle.toggle_diff()               # show/hide the diff pane
handle.toggle_read_only()
handle.toggle_gutter()
handle.change_font_size(+1)        # or -1
handle.set_language(fce.CodeLanguage.PYTHON)  # set directly
handle.choose_language()           # or open the language picker

handle.value          # current editor content (str)
handle.current_path   # path of open file, or None
handle.dirty          # True if there are unsaved changes
handle.search_open    # True while the find/replace bar is shown

Every action is safe to call from an embedder's own keyboard handler — pair it with register_keyboard_shortcuts=False to own the key bindings yourself.

Other public exports

The package also exports these utilities from fce_enhanced:

Export Description
EditorHandle Imperative handle for driving the editor component
SearchReplaceBar Reusable search/replace component
DiffPane Reusable unified-diff component
compute_matches() Pure function: find search matches in text
compute_unified_diff() Pure function: unified diff + add/remove counts
open_file() / save_file() Async platform-aware file dialogs
language_for_path() Detect CodeLanguage from a file path
EXTENSION_TO_LANGUAGE Dict mapping file extensions to CodeLanguage
THEMES / DEFAULT_THEME / theme_display_name() Theme utilities
main() / run() Entry points for standalone mode

Features

  • File operations — Open, Save, Save As, Close, and Revert to Saved with unsaved-changes confirmation
  • Native file dialogs — AppleScript dialogs on macOS (with extension filtering), Flet's built-in FilePicker on other platforms
  • Search & Replace — Find toolbar with match counting, case sensitivity toggle, whole word matching, prev/next navigation (Enter navigates to next match), Replace and Replace All
  • Command Palette — Searchable list of all available commands; type to filter (Cmd+Shift+P / Ctrl+Shift+P)
  • Theme Selector — 80+ built-in syntax highlighting themes via a searchable dialog (type to filter)
  • Go to Line — Jump to a specific line number (Cmd+G / Ctrl+G)
  • Read-Only Mode — Toggle editing lock (Cmd+L / Ctrl+L)
  • Font Size Controls — Increase/decrease font size (Cmd+= / Cmd+-)
  • Language Selector — Choose syntax highlighting language from a searchable dialog (type to filter); auto-detected on file open, and Save As defaults to the matching file extension
  • Language Detection — Automatic syntax highlighting for 40+ file extensions
  • Dirty-File Tracking — Visual indicator for unsaved changes
  • Diff Pane — Toggleable unified diff view showing changes since last save, with green/red syntax coloring (Cmd+D / Ctrl+D)
  • Gutter Toggle — Show or hide the line-number gutter (Shift+Cmd+G / Ctrl+Shift+G)
  • Ruff on Save — Auto-runs ruff check --fix and ruff format on .py files; silently skips if ruff is not installed (no error). Remaining lint warnings are shown in a snackbar, and the editor auto-reloads the formatted content. Toggleable from the toolbar
  • Status Bar — Line, column, language, and selection info

Keyboard shortcuts

Action macOS Windows / Linux
Open File ⌘O Ctrl+O
Save ⌘S Ctrl+S
Save As ⇧⌘S Ctrl+Shift+S
Close File ⌘W Ctrl+W
Revert to Saved ⇧⌘R Ctrl+Shift+R
Find ⌘F Ctrl+F
Find and Replace ⌥⌘F Ctrl+H
Toggle Diff ⌘D Ctrl+D
Toggle Gutter ⇧⌘G Ctrl+Shift+G
Go to Line ⌘G Ctrl+G
Toggle Read-Only ⌘L Ctrl+L
Increase Font Size ⌘+ Ctrl++
Decrease Font Size ⌘- Ctrl+-
Command Palette ⇧⌘P Ctrl+Shift+P
Help F1 F1
Close Search Bar Esc Esc

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

License

MIT

Development

Code style is enforced with ruff via pre-commit hooks:

pre-commit run --all-files

Run tests:

pytest

Built With

  • Flet — Build multi-platform apps in Python powered by Flutter
  • flet-code-editor — Code editor control for Flet with syntax highlighting
  • ruff — Fast Python linter and formatter

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fce_enhanced-0.2.2.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fce_enhanced-0.2.2-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

Details for the file fce_enhanced-0.2.2.tar.gz.

File metadata

  • Download URL: fce_enhanced-0.2.2.tar.gz
  • Upload date:
  • Size: 23.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fce_enhanced-0.2.2.tar.gz
Algorithm Hash digest
SHA256 776ab69df74ee057ee21547b8927a9b2f05564fa057b452b7337960ccbbe34e6
MD5 eeeda9891e1951703156675a183392fa
BLAKE2b-256 5a06640c51ac64a1017670f9dbdad8db4dd96a9b374b1a68c49ab6456e259197

See more details on using hashes here.

Provenance

The following attestation bundles were made for fce_enhanced-0.2.2.tar.gz:

Publisher: publish.yml on oktl/flet-fce-enhanced

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fce_enhanced-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: fce_enhanced-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 27.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fce_enhanced-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 652a2d1988edb897732ebde8ff40b31d5478afb001e05b1c9cac5bf7cd3a69a0
MD5 a06ed5f5d52c3929416592e7702d1630
BLAKE2b-256 7f202831fe31e1e2419c4f27fc2375ecc9d7571a324d9dd9b39cec2ff6f876dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for fce_enhanced-0.2.2-py3-none-any.whl:

Publisher: publish.yml on oktl/flet-fce-enhanced

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 files

0.2.1

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page