Skip to content

CodeEditor control#6162

Open
FeodorFitsner wants to merge 25 commits intomainfrom
flet-code-editor
Open

CodeEditor control#6162
FeodorFitsner wants to merge 25 commits intomainfrom
flet-code-editor

Conversation

@FeodorFitsner
Copy link
Contributor

@FeodorFitsner FeodorFitsner commented Feb 12, 2026

Summary by Sourcery

Add a new CodeEditor extension package for editing and highlighting source code in Flet apps, wire it into the Flutter client, Python SDK, docs, examples, and tests, and tweak docs tooling and config to support it.

New Features:

  • Introduce a flet-code-editor Python package and corresponding Flutter extension providing a CodeEditor control with syntax highlighting, gutter styling, selection handling, and folding APIs.
  • Add CodeTheme and GutterStyle helper types to configure editor theming and gutter appearance from Python.
  • Provide new CodeEditor example apps demonstrating basic usage, selection handling, and folding behavior, plus integration tests that capture golden screenshots for documentation.

Enhancements:

  • Document the new CodeEditor control and its related types in the Flet docs site and extend navigation to include them.
  • Register the new flet-code-editor extension across the Python SDK, Flet core package, Flutter client app, and CI to ensure it is built, tested, and distributed.
  • Add a fast docs-serve task and an option to skip remote PyPI index fetching to speed up local docs development.
  • Adjust various MkDocs / xref templates and config, including limiting preloaded modules, to support the new docs content.

CI:

  • Include flet-code-editor in CI workflows for building, testing, and packaging alongside other Flet extensions.

Documentation:

  • Add user-facing documentation pages for the CodeEditor control and its CodeTheme and GutterStyle types, including installation instructions and embedded examples with screenshots.

Tests:

  • Add golden screenshot integration tests for the new CodeEditor examples to validate their rendered appearance in the docs.

Introduces the flet-code-editor extension for editing and highlighting source code in Flet apps. Adds Python and Flutter package files, example usage scripts, documentation, and integrates the extension into the client and docs navigation. Updates dependencies in pubspec files and pyproject.toml to include flet-code-editor.
Renamed the 'theme' property to 'code_theme' in CodeEditor and updated all references in examples and documentation. Removed legacy 'line_number_style' in favor of 'gutter_style' for consistency. Updated the Flutter implementation to match the new property names and removed related legacy code.
Moved autocompletion logic from _CodeEditorControlState to a new _FletCodeController class, enabling better encapsulation and control. The editor now manages autocompletion state and suggestions directly through the controller, removing the previous RawAutocomplete-based implementation.
Refactored Python code editor examples for clarity and updated usage, including code samples and UI elements. In the Flutter code editor widget, wrapped the code field in a SingleChildScrollView to improve scrolling behavior. Also updated dependencies in pubspec.lock and made minor code cleanups.
Eliminated support for read-only and visible section names in the code editor, including related properties, methods, and controller logic in both Python and Dart implementations. This simplifies the code editor API and internal logic by removing unused or deprecated section-based features.
Simplified language name resolution in the code editor by directly accessing the control property instead of using a helper method. Removed the 'on_selection_change' flag check, so selection change events are always triggered when the selection is valid. Updated the Python example to adjust the selection range and event handler output.
Moved theme and gutter style parsing logic to a new utils/code_editor.dart file and extracted the custom code controller to utils/flet_code_controller.dart. Updated CodeEditorControl to use the new FletCodeController and utility functions, improving code organization and maintainability. Also registered flet-code-editor in the CI workflow.
Introduces a new 'padding' property to the CodeEditor in both Python and Dart implementations, allowing customization of padding around the editor content.
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 12, 2026

Deploying flet-examples with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7d6bb8a
Status: ✅  Deploy successful!
Preview URL: https://f1dc9fd2.flet-examples.pages.dev
Branch Preview URL: https://flet-code-editor.flet-examples.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 12, 2026

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7d6bb8a
Status: ✅  Deploy successful!
Preview URL: https://b2651860.flet-docs.pages.dev
Branch Preview URL: https://flet-code-editor.flet-docs.pages.dev

View logs

Update sdk/python/packages/flet/mkdocs.yml to add the CodeEditor nav entry under the earlier controls list and remove the duplicate entry further down the file. This fixes navigation duplication and ensures CodeEditor appears in the correct section.
Update documentation and package metadata to register the new extension. SKILL.md now notes adding the extension to sdk/python/packages/flet/pyproject.toml, and sdk/python/packages/flet/pyproject.toml was updated to include "flet-code-editor" in the extensions list.
Replace the deprecated `value`/TextEditingValue API with an explicit `selection` property and add `autofocus` support. Update Python package exports to remove TextEditingValue, update type docs/comments, and wire `on_selection_change` to reflect caret/selection updates. Flutter control now syncs an explicit `selection` field, sends selection updates to the host, and performs a one-shot autofocus when requested. Examples were updated to use the new `text` + `selection`/autofocus API and demonstrate selection handling and helper buttons.
Rename CodeEditor API from text/full_text to a single value property and update usages. Example apps now pass value instead of text. Python control class docstring updated and full_text removed. Flutter control implementation renamed internal state (_text/_fullText -> _value), reads/writes controller.fullText as the value, and updates change/selection events and property sync to use value and visible text for selected_text.
Reorganize CodeEditor documentation: remove old sdk/python/packages/flet/docs/code_editor/index.md and text_editing_value.md, and add a new index.md at sdk/python/packages/flet/docs/codeeditor/index.md (expanded with supported languages and named themes). Rename type docs paths under types/ to codetheme.md and gutterstyle.md and update mkdocs.yml to point to the new codeeditor/* locations.
Replace dynamic "|get_template" include calls with explicit ".html.jinja" filenames across material templates. Updated attribute, class, docstring/attributes, and summary templates to include concrete template paths to ensure correct resolution (yore bump change). Files modified: sdk/python/packages/flet/docs/templates/python_xref/material/{attribute.html.jinja,class.html.jinja,docstring/attributes.html.jinja,summary.html.jinja}.
Add a serve-docs-fast Taskfile task to run MkDocs from packages/flet without fetching the PyPI index (uses FLET_DOCS_SKIP_PYPI_INDEX env). Update docs macros to honor that env and return a skip notice when set. Move large lists of supported languages and named themes into CodeEditor docstrings (removed from the markdown page) to keep the docs page concise. Remove flet_ads from mkdocs preload_modules to avoid preloading that module.
Expand the CodeTheme docstring to enumerate the supported token style names and provide usage details. This adds a comprehensive list of accepted keys for the styles mapping (e.g. `keyword`, `string`, `comment`, `function`, etc.) to clarify which token names can be used for syntax highlighting.
Reorganize integration test assets for the color_picker example by moving golden macOS images and the test file from sdk/python/packages/flet/integration_tests/examples/color_picker/ to sdk/python/packages/flet/integration_tests/examples/extensions/color_picker/. This preserves file contents (100% similarity) while adjusting the directory structure for extensions grouping.
Add CodeEditor example package changes: create package init, guard example entrypoints with if __name__ == '__main__', and update docs to include example images and structured examples. Add integration test for CodeEditor examples with golden screenshots and include corresponding golden images for macOS.
@FeodorFitsner FeodorFitsner marked this pull request as ready for review February 14, 2026 02:56
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

Register the flet-color-pickers package by adding it to the extensions array in sdk/python/packages/flet/pyproject.toml. This ensures the color picker extension is included with the Flet Python package.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new extensible CodeEditor control and wires it through the Python SDK, Flutter client, CI, examples, and documentation.

Changes:

  • Register flet-code-editor across Python workspace deps, Flutter client deps, and CI.
  • Add Python/Flutter implementation for CodeEditor plus supporting data types and docs pages.
  • Add examples and screenshot-based integration test coverage for the new control docs/examples.

Reviewed changes

Copilot reviewed 36 out of 49 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
sdk/python/pyproject.toml Adds flet-code-editor to Python SDK workspace dependencies.
sdk/python/packages/flet/pyproject.toml Registers the new extension package for the main flet Python package.
sdk/python/packages/flet/mkdocs.yml Adds CodeEditor docs nav entries and adjusts mkdocstrings preload modules.
sdk/python/packages/flet/integration_tests/examples/extensions/code_editor/test_code_editor_examples.py Adds screenshot-based integration coverage for CodeEditor examples.
sdk/python/packages/flet/docs/templates/python_xref/material/summary.html.jinja Updates template includes to explicit .html.jinja filenames.
sdk/python/packages/flet/docs/templates/python_xref/material/docstring/attributes.html.jinja Updates template include to explicit .html.jinja filename.
sdk/python/packages/flet/docs/templates/python_xref/material/class.html.jinja Updates template includes to explicit .html.jinja filenames.
sdk/python/packages/flet/docs/templates/python_xref/material/attribute.html.jinja Updates template includes to explicit .html.jinja filenames.
sdk/python/packages/flet/docs/extras/macros/init.py Adds env toggle to skip PyPI index fetching for faster local docs.
sdk/python/packages/flet/docs/codeeditor/types/gutterstyle.md Adds docs page for GutterStyle.
sdk/python/packages/flet/docs/codeeditor/types/codetheme.md Adds docs page for CodeTheme.
sdk/python/packages/flet/docs/codeeditor/index.md Adds CodeEditor landing page with usage and examples.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/pubspec.yaml Introduces Flutter package manifest for the extension.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/lib/src/utils/flet_code_controller.dart Adds FletCodeController with autocompletion gating and insertion logic.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/lib/src/utils/code_editor.dart Adds parsing helpers for CodeThemeData and GutterStyle.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/lib/src/extension.dart Registers the Flutter-side CodeEditor widget factory in a Flet extension.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/lib/src/code_editor.dart Implements the Flutter CodeEditorControl widget and event wiring.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/lib/flet_code_editor.dart Exports the extension entrypoint.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/analysis_options.yaml Adds Dart analyzer configuration.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/.metadata Adds Flutter project metadata for the new package.
sdk/python/packages/flet-code-editor/src/flutter/flet_code_editor/.gitignore Adds Flutter package-specific ignore rules.
sdk/python/packages/flet-code-editor/src/flet_code_editor/types.py Adds Python types (CodeTheme, GutterStyle) for CodeEditor configuration.
sdk/python/packages/flet-code-editor/src/flet_code_editor/code_editor.py Adds Python CodeEditor control API surface (props + folding/focus methods).
sdk/python/packages/flet-code-editor/src/flet_code_editor/init.py Exposes the extension’s public Python symbols.
sdk/python/packages/flet-code-editor/pyproject.toml Adds Python package metadata for flet-code-editor.
sdk/python/packages/flet-code-editor/README.md Adds package README with install/docs links and examples pointer.
sdk/python/packages/flet-code-editor/LICENSE Adds Apache-2.0 license file for the new package.
sdk/python/packages/flet-code-editor/CHANGELOG.md Adds initial changelog for the new package.
sdk/python/examples/controls/code_editor/example_1.py Adds a basic CodeEditor usage example.
sdk/python/examples/controls/code_editor/example_2.py Adds selection + autocompletion example.
sdk/python/examples/controls/code_editor/example_3.py Adds folding + initial selection example.
sdk/python/Taskfile.yml Adds a “serve-docs-fast” task that skips PyPI index fetch.
client/pubspec.yaml Adds Flutter client dependency on the new flet_code_editor extension.
client/pubspec.lock Locks new transitive deps introduced by flutter_code_editor integration.
client/lib/main.dart Registers flet_code_editor.Extension() in the Flutter client startup.
.github/workflows/ci.yml Adds flet-code-editor package to CI build/test matrices.
.codex/skills/implement-flet-extension/SKILL.md Updates extension implementation checklist to include flet extension registration.
Comments suppressed due to low confidence (1)

sdk/python/packages/flet/integration_tests/examples/extensions/code_editor/test_code_editor_examples.py:1

  • pytest-asyncio’s @pytest.mark.asyncio marker commonly supports scope=... (or no args) rather than loop_scope=...; using an unknown keyword can cause the test collection to error. Consider switching to @pytest.mark.asyncio (or @pytest.mark.asyncio(scope=\"function\") if supported by the pinned pytest-asyncio version in this repo).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


[project.urls]
Homepage = "https://flet.dev"
Documentation = "https://docs.flet.dev/code_editor"
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation URL uses /code_editor, but the MkDocs nav path added in this PR is codeeditor/index.md (which typically renders as /codeeditor/). Consider aligning the URL to the actual site path to avoid broken links.

Suggested change
Documentation = "https://docs.flet.dev/code_editor"
Documentation = "https://docs.flet.dev/codeeditor/"

Copilot uses AI. Check for mistakes.

## Documentation

Detailed documentation to this package can be found [here](https://docs.flet.dev/code_editor/).
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README links to /code_editor/, but the docs nav page introduced is codeeditor/index.md (commonly published at /codeeditor/). Consider updating this link (and keeping it consistent with the package metadata URL) so users don’t land on a 404.

Suggested change
Detailed documentation to this package can be found [here](https://docs.flet.dev/code_editor/).
Detailed documentation to this package can be found [here](https://docs.flet.dev/codeeditor/).

Copilot uses AI. Check for mistakes.
`keyword`, `link`, `link_label`, `literal`, `meta`, `meta-keyword`,
`meta-string`, `name`, `number`, `operator`, `params`, `pattern-match`, `quote`,
`regexp`, `root`, `section`, `selector-attr`, `selector-class`, `selector-id`,
`selector-pseudo`, `selector-tag`, `string`, `strong`, `stronge`, `subst`,
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the documented token style names: stronge should be strong.

Suggested change
`selector-pseudo`, `selector-tag`, `string`, `strong`, `stronge`, `subst`,
`selector-pseudo`, `selector-tag`, `string`, `strong`, `subst`,

Copilot uses AI. Check for mistakes.
`meta-string`, `name`, `number`, `operator`, `params`, `pattern-match`, `quote`,
`regexp`, `root`, `section`, `selector-attr`, `selector-class`, `selector-id`,
`selector-pseudo`, `selector-tag`, `string`, `strong`, `stronge`, `subst`,
`subtr`, `symbol`, `tag`, `template-tag`, `template-variable`, `title`, `type`,
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the documented token style names: subtr is likely intended to be subst (which is already listed on the previous line). Consider removing subtr to avoid confusing users.

Suggested change
`subtr`, `symbol`, `tag`, `template-tag`, `template-variable`, `title`, `type`,
`symbol`, `tag`, `template-tag`, `template-variable`, `title`, `type`,

Copilot uses AI. Check for mistakes.
}

Future<dynamic> _invokeMethod(String name, dynamic args) async {
debugPrint("CodeEditor.$name($args)");
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using (_controller as dynamic) bypasses static checking and can turn missing/changed API methods into runtime NoSuchMethodErrors. Prefer calling typed APIs directly (if available on CodeController), or add explicit wrapper methods to FletCodeController so the compiler enforces compatibility with the pinned flutter_code_editor version.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +63
(_controller as dynamic).foldCommentAtLineZero();
break;
case "fold_imports":
(_controller as dynamic).foldImports();
break;
case "fold_at":
final line = parseInt(args["line_number"]);
if (line != null) {
(_controller as dynamic).foldAt(line);
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using (_controller as dynamic) bypasses static checking and can turn missing/changed API methods into runtime NoSuchMethodErrors. Prefer calling typed APIs directly (if available on CodeController), or add explicit wrapper methods to FletCodeController so the compiler enforces compatibility with the pinned flutter_code_editor version.

Suggested change
(_controller as dynamic).foldCommentAtLineZero();
break;
case "fold_imports":
(_controller as dynamic).foldImports();
break;
case "fold_at":
final line = parseInt(args["line_number"]);
if (line != null) {
(_controller as dynamic).foldAt(line);
_controller.foldCommentAtLineZero();
break;
case "fold_imports":
_controller.foldImports();
break;
case "fold_at":
final line = parseInt(args["line_number"]);
if (line != null) {
_controller.foldAt(line);

Copilot uses AI. Check for mistakes.
}

Future<dynamic> _invokeMethod(String name, dynamic args) async {
debugPrint("CodeEditor.$name($args)");
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unconditional debugPrint calls in build() and method invocation can generate very noisy logs and add overhead. Consider guarding them with kDebugMode (or removing them) so production builds and large pages aren’t impacted.

Suggested change
debugPrint("CodeEditor.$name($args)");
if (kDebugMode) {
debugPrint("CodeEditor.$name($args)");
}

Copilot uses AI. Check for mistakes.

@override
Widget build(BuildContext context) {
debugPrint("CodeEditor build: ${widget.control.id}");
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unconditional debugPrint calls in build() and method invocation can generate very noisy logs and add overhead. Consider guarding them with kDebugMode (or removing them) so production builds and large pages aren’t impacted.

Copilot uses AI. Check for mistakes.
Delete the example_2.gif binary asset from sdk/python/packages/flet/docs/assets/datatable2 to clean up an unused documentation image.
Comment on lines +23 to +25
If provided,
[`DataTable.divider_thickness`][flet.DataTable.divider_thickness]
has no effect.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will suggest we have the "2" in the visible part, so it makes sense with respect to context.

[`DataTable2.divider_thickness`][flet.DataTable.divider_thickness]

Same for other parts.

- BaseAd: ads/basead.md
- InterstitialAd: ads/interstitialad.md
# - NativeAd: ads/nativead.md
- NativeAd: ads/nativead.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isnt ready yet as far as I can remember 😅
(except if you've tested it?)

Comment on lines +14 to +17
/// details | Supported style names
type: note

`addition`, `attr`, `attribute`, `built_in`, `builtin-name`, `bullet`, `class`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provide as an enum?
Or even better, we could have something like this: https://docs.flet.dev/types/markdowncustomcodetheme/#flet.MarkdownCustomCodeTheme

Comment on lines +50 to +55
/// details | Supported named themes
type: note

`a11y-dark`, `a11y-light`, `agate`, `an-old-hope`, `androidstudio`, `arduino-light`,
`arta`, `ascetic`, `atelier-cave-dark`, `atelier-cave-light`, `atelier-dune-dark`,
`atelier-dune-light`, `atelier-estuary-dark`, `atelier-estuary-light`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indirect=["flet_app_function"],
)
@pytest.mark.asyncio(loop_scope="function")
async def test_code_editor_examples(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function name should have name of control

@@ -0,0 +1,33 @@
import pytest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why make this file end with _examples ?

Comment on lines +168 to +172
final explicitSelection = parseTextSelection(
widget.control.get("selection"),
minOffset: 0,
maxOffset: _controller.text.length,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

widget.control.getTextSelection ?

Comment on lines +189 to +190
final autocompletionEnabled =
widget.control.getBool("autocompletion_enabled", false)!;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will suggest renaming to something like autocomplete

Comment on lines +206 to +207
textStyle:
parseTextStyle(widget.control.get("text_style"), Theme.of(context)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

widget.control.getTextStyle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants