Conversation
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.
Deploying flet-examples with
|
| 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 |
Deploying flet-docs with
|
| 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 |
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.
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.
There was a problem hiding this comment.
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-editoracross Python workspace deps, Flutter client deps, and CI. - Add Python/Flutter implementation for
CodeEditorplus 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.asynciomarker commonly supportsscope=...(or no args) rather thanloop_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" |
There was a problem hiding this comment.
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.
| Documentation = "https://docs.flet.dev/code_editor" | |
| Documentation = "https://docs.flet.dev/codeeditor/" |
|
|
||
| ## Documentation | ||
|
|
||
| Detailed documentation to this package can be found [here](https://docs.flet.dev/code_editor/). |
There was a problem hiding this comment.
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.
| 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/). |
| `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`, |
There was a problem hiding this comment.
Typo in the documented token style names: stronge should be strong.
| `selector-pseudo`, `selector-tag`, `string`, `strong`, `stronge`, `subst`, | |
| `selector-pseudo`, `selector-tag`, `string`, `strong`, `subst`, |
| `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`, |
There was a problem hiding this comment.
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.
| `subtr`, `symbol`, `tag`, `template-tag`, `template-variable`, `title`, `type`, | |
| `symbol`, `tag`, `template-tag`, `template-variable`, `title`, `type`, |
sdk/python/packages/flet-code-editor/src/flet_code_editor/code_editor.py
Show resolved
Hide resolved
| } | ||
|
|
||
| Future<dynamic> _invokeMethod(String name, dynamic args) async { | ||
| debugPrint("CodeEditor.$name($args)"); |
There was a problem hiding this comment.
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.
| (_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); |
There was a problem hiding this comment.
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.
| (_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); |
| } | ||
|
|
||
| Future<dynamic> _invokeMethod(String name, dynamic args) async { | ||
| debugPrint("CodeEditor.$name($args)"); |
There was a problem hiding this comment.
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.
| debugPrint("CodeEditor.$name($args)"); | |
| if (kDebugMode) { | |
| debugPrint("CodeEditor.$name($args)"); | |
| } |
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| debugPrint("CodeEditor build: ${widget.control.id}"); |
There was a problem hiding this comment.
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.
Delete the example_2.gif binary asset from sdk/python/packages/flet/docs/assets/datatable2 to clean up an unused documentation image.
| If provided, | ||
| [`DataTable.divider_thickness`][flet.DataTable.divider_thickness] | ||
| has no effect. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
This isnt ready yet as far as I can remember 😅
(except if you've tested it?)
| /// details | Supported style names | ||
| type: note | ||
|
|
||
| `addition`, `attr`, `attribute`, `built_in`, `builtin-name`, `bullet`, `class`, |
There was a problem hiding this comment.
Provide as an enum?
Or even better, we could have something like this: https://docs.flet.dev/types/markdowncustomcodetheme/#flet.MarkdownCustomCodeTheme
| /// 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`, |
There was a problem hiding this comment.
Looks like https://docs.flet.dev/types/markdowncodetheme ?
| indirect=["flet_app_function"], | ||
| ) | ||
| @pytest.mark.asyncio(loop_scope="function") | ||
| async def test_code_editor_examples( |
There was a problem hiding this comment.
function name should have name of control
| @@ -0,0 +1,33 @@ | |||
| import pytest | |||
There was a problem hiding this comment.
why make this file end with _examples ?
| final explicitSelection = parseTextSelection( | ||
| widget.control.get("selection"), | ||
| minOffset: 0, | ||
| maxOffset: _controller.text.length, | ||
| ); |
There was a problem hiding this comment.
widget.control.getTextSelection ?
| final autocompletionEnabled = | ||
| widget.control.getBool("autocompletion_enabled", false)!; |
There was a problem hiding this comment.
will suggest renaming to something like autocomplete
| textStyle: | ||
| parseTextStyle(widget.control.get("text_style"), Theme.of(context)), |
There was a problem hiding this comment.
widget.control.getTextStyle
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:
Enhancements:
CI:
Documentation:
Tests: