flet-code-editor-dsl 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flet_code_editor_dsl-0.3.1/src/flet_code_editor_dsl.egg-info → flet_code_editor_dsl-0.3.2}/PKG-INFO +27 -24
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/README.md +26 -23
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/pyproject.toml +1 -1
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl/__init__.py +3 -1
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl/flet_code_editor_dsl.py +7 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2/src/flet_code_editor_dsl.egg-info}/PKG-INFO +27 -24
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/lib/src/code_editor.dart +65 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/lib/src/tokenizer.dart +11 -2
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/pubspec.yaml +1 -1
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/LICENSE +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/MANIFEST.in +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/setup.cfg +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl/language.py +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl.egg-info/SOURCES.txt +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl.egg-info/dependency_links.txt +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl.egg-info/requires.txt +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl.egg-info/top_level.txt +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/__init__.py +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/__init__.py +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/lib/flet_code_editor_dsl.dart +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/lib/src/extension.dart +0 -0
- {flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flutter/flet_code_editor_dsl/lib/src/regex_highlighter.dart +0 -0
{flet_code_editor_dsl-0.3.1/src/flet_code_editor_dsl.egg-info → flet_code_editor_dsl-0.3.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-code-editor-dsl
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Flet code editors with syntax highlighting: EditorTokens (tokenizer) and EditorRegex (regex)
|
|
5
5
|
Author-email: obgwew <obgwew@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,7 +25,7 @@ Dynamic: license-file
|
|
|
25
25
|
## Table of Contents
|
|
26
26
|
|
|
27
27
|
1. [Overview](#overview)
|
|
28
|
-
2. [What's New in 0.3.
|
|
28
|
+
2. [What's New in 0.3.2 / Migration](#whats-new-in-032--migration)
|
|
29
29
|
3. [Features](#features)
|
|
30
30
|
4. [Requirements](#requirements)
|
|
31
31
|
5. [Installation](#installation)
|
|
@@ -97,9 +97,9 @@ lang = ce.Language(
|
|
|
97
97
|
|
|
98
98
|
and hand `lang.to_json()` to `EditorTokens`.
|
|
99
99
|
|
|
100
|
-
## What's New in 0.3.
|
|
100
|
+
## What's New in 0.3.2 / Migration
|
|
101
101
|
|
|
102
|
-
### 0.3.
|
|
102
|
+
### 0.3.2
|
|
103
103
|
|
|
104
104
|
| Change | Details |
|
|
105
105
|
|--------|---------|
|
|
@@ -109,6 +109,8 @@ and hand `lang.to_json()` to `EditorTokens`.
|
|
|
109
109
|
| **Touch support** | New selection menu at the caret/handles, optional toolbar and cursor pad, magnifier, `scroll_mode`. See [Mobile / Touch Features](#mobile--touch-features). |
|
|
110
110
|
| **Paste fix** | Cut/copy/paste from the new menu/toolbar read the clipboard directly and normalize line endings and control characters before inserting. |
|
|
111
111
|
| **New Dart files** | `regex_highlighter.dart` (regex engine). `code_editor.dart` is now shared by both controls. The old `src/flet_code_editor_dsl.dart` (`CodeField` widget) was deleted. |
|
|
112
|
+
| **Number literals** | `0b…` now accepts only `0`/`1` and `0o…` only `0`–`7` (before, they accepted any hex digit, so `0b1010f` was one number). `0x…` is unchanged. |
|
|
113
|
+
| **Sigils** | If the longest matching prefix has no name after it, shorter prefixes are tried next (for example `$$` and `$` defined together: a lone `$$ ` now falls back to `$`). |
|
|
112
114
|
|
|
113
115
|
Rename in your code:
|
|
114
116
|
|
|
@@ -120,11 +122,11 @@ ce.FletCodeField(rules=[...]) ce.EditorRegex(rules=[...])
|
|
|
120
122
|
|
|
121
123
|
Because the Dart side changed, **rebuild your app** after upgrading.
|
|
122
124
|
|
|
123
|
-
###
|
|
125
|
+
### Migrating from the original `CodeEditor` API
|
|
124
126
|
|
|
125
127
|
The earlier regex-based `CodeEditor` control and its `rule()` / `group()` / `pair()` helpers no longer exist.
|
|
126
128
|
|
|
127
|
-
| Original API | 0.2
|
|
129
|
+
| Original API | 0.3.2 |
|
|
128
130
|
|-------|-------|
|
|
129
131
|
| Control `CodeEditor` | `EditorTokens` (tokenizer) and `EditorRegex` (regex) |
|
|
130
132
|
| `rule()`, `group()` + `rules_json()` | `Language(words=[WordGroup(...)], strings=..., ...)` + `Language.to_json()`; `HighlightRule` list for `EditorRegex` |
|
|
@@ -178,17 +180,17 @@ version = "1.0.0"
|
|
|
178
180
|
requires-python = ">=3.10"
|
|
179
181
|
dependencies = [
|
|
180
182
|
"flet>=0.85.2",
|
|
181
|
-
"flet-code-editor-dsl>=0.3.
|
|
183
|
+
"flet-code-editor-dsl>=0.3.2",
|
|
182
184
|
]
|
|
183
185
|
```
|
|
184
186
|
|
|
185
|
-
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.
|
|
187
|
+
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.2"`. Upgrade with `pip install --upgrade flet-code-editor-dsl`.
|
|
186
188
|
|
|
187
189
|
### Option 2: GitHub
|
|
188
190
|
|
|
189
191
|
```bash
|
|
190
192
|
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git"
|
|
191
|
-
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.
|
|
193
|
+
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.2" # pinned
|
|
192
194
|
```
|
|
193
195
|
|
|
194
196
|
Inside `pyproject.toml`:
|
|
@@ -445,13 +447,13 @@ Changing the language/rules, `syntax_highlighting`, `show_errors` or `code_foldi
|
|
|
445
447
|
|
|
446
448
|
## Mobile / Touch Features
|
|
447
449
|
|
|
448
|
-
New in 0.3.
|
|
450
|
+
New in 0.3.2. They apply to both controls. Properties that take `None` mean **automatic**: enabled on Android/iOS, disabled elsewhere.
|
|
449
451
|
|
|
450
452
|
| Property | Type | Default | Description |
|
|
451
453
|
|----------|------|---------|-------------|
|
|
452
454
|
| `selection_menu` | `bool` | `True` | Show the cut/copy/paste menu at the caret and selection handles (Android/iOS only). |
|
|
453
|
-
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu. Also accepts `"undo"`, `"redo"`. |
|
|
454
|
-
| `mobile_controls` | `bool \| None` | `None` (
|
|
455
|
+
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu, in order (see `ce.DEFAULT_SELECTION_MENU_ITEMS`). Also accepts `"undo"`, `"redo"`. Unknown ids are ignored. |
|
|
456
|
+
| `mobile_controls` | `bool \| None` | `None` (auto) | Show the extra toolbar. Auto = shown on Android/iOS, hidden elsewhere; `True` / `False` force it. |
|
|
455
457
|
| `toolbar_items` | `list[str]` | all items | Toolbar buttons, see below. |
|
|
456
458
|
| `toolbar_position` | `ToolbarPosition` | `BOTTOM` | `BOTTOM` or `TOP`. |
|
|
457
459
|
| `cursor_pad` | `bool \| None` | `None` (auto) | Draggable pad inside the toolbar. Only visible when the toolbar is shown. |
|
|
@@ -474,11 +476,12 @@ ce.EditorTokens(
|
|
|
474
476
|
|
|
475
477
|
- *Cut* and *Copy* appear only when something is selected. *Cut*, *Paste*, *Undo* and *Redo* are hidden in `read_only` mode.
|
|
476
478
|
- The menu is shown on **Android and iOS only**. On desktop, the usual keyboard shortcuts apply.
|
|
477
|
-
- Set `selection_menu=False` to disable it.
|
|
479
|
+
- Set `selection_menu=False` to disable it. The menu is rebuilt every time it opens, so changing `selection_menu_items` or `read_only` at runtime takes effect immediately.
|
|
480
|
+
- It works together with the optional toolbar: both use the same cut/copy/paste implementation (see [Paste behavior](#paste-behavior)).
|
|
478
481
|
|
|
479
482
|
### Extra toolbar and cursor pad
|
|
480
483
|
|
|
481
|
-
An
|
|
484
|
+
An extra bar next to the editor (arrows, undo/redo, home/end, tab, cursor pad). With the default `mobile_controls=None` it is **shown automatically on Android/iOS** and hidden on desktop; pass `True` or `False` to force it:
|
|
482
485
|
|
|
483
486
|
```python
|
|
484
487
|
ce.EditorTokens(
|
|
@@ -640,7 +643,7 @@ sigils=[ce.Sigil("$", "#9CDCFE"), ce.Sigil("@", "#4FC1FF"), ce.Sigil("%", "#D7BA
|
|
|
640
643
|
|
|
641
644
|
### Numbers, operators, punctuation, identifiers
|
|
642
645
|
|
|
643
|
-
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F
|
|
646
|
+
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F` hex, `0b1010` binary, `0o755` octal; each prefix accepts only its own digits and `_`). A number ends where it ends: `10px` is the number `10` followed by the identifier `px`. Identifiers cannot start with a digit. Set `numbers=False` if digits should not be treated specially.
|
|
644
647
|
|
|
645
648
|
**Operators** — each character in `Language.operators` is an operator character; a *run* of operator characters (`==`, `<=`, `&&`) becomes **one** token with `TokenColors.operator`.
|
|
646
649
|
|
|
@@ -711,7 +714,7 @@ errors=ce.ErrorRules(
|
|
|
711
714
|
)
|
|
712
715
|
```
|
|
713
716
|
|
|
714
|
-
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
717
|
+
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Not allowed: goto*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
715
718
|
|
|
716
719
|
### `FoldRule` and `fold_by_indent` (code folding)
|
|
717
720
|
|
|
@@ -1086,7 +1089,7 @@ page.add(
|
|
|
1086
1089
|
| Change | Rebuild needed? |
|
|
1087
1090
|
|--------|-----------------|
|
|
1088
1091
|
| Editing Python code, `value`, `language` / `Language(...)`, `rules`, colors, fonts, flags, sizes, layout, mobile options | No — sent to the client at runtime. |
|
|
1089
|
-
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example
|
|
1092
|
+
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example when upgrading to 0.3.2) | **Yes** |
|
|
1090
1093
|
| Upgrading Flet itself to a new major/minor version | Yes |
|
|
1091
1094
|
| Adding or removing other Flet extensions | Yes |
|
|
1092
1095
|
|
|
@@ -1133,7 +1136,7 @@ To test the library **before publishing it**:
|
|
|
1133
1136
|
```toml
|
|
1134
1137
|
dependencies = [
|
|
1135
1138
|
"flet>=0.85.2",
|
|
1136
|
-
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.
|
|
1139
|
+
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.2-py3-none-any.whl",
|
|
1137
1140
|
]
|
|
1138
1141
|
```
|
|
1139
1142
|
|
|
@@ -1187,7 +1190,7 @@ flet-code-editor-dsl/
|
|
|
1187
1190
|
├── __init__.py
|
|
1188
1191
|
└── flet_code_editor_dsl/
|
|
1189
1192
|
├── __init__.py
|
|
1190
|
-
├── pubspec.yaml # Flutter package (v0.3.
|
|
1193
|
+
├── pubspec.yaml # Flutter package (v0.3.2)
|
|
1191
1194
|
└── lib/
|
|
1192
1195
|
├── flet_code_editor_dsl.dart # Exports Extension
|
|
1193
1196
|
└── src/
|
|
@@ -1221,7 +1224,7 @@ flet-code-editor-dsl/
|
|
|
1221
1224
|
|
|
1222
1225
|
## Known Limitations
|
|
1223
1226
|
|
|
1224
|
-
- **Touch features are new in 0.3.
|
|
1227
|
+
- **Touch features are new in 0.3.2** and have had limited testing on real devices; please report problems with your device, OS version and Flet version.
|
|
1225
1228
|
- **The magnifier does not follow the selection handles** (they are owned by `re_editor`); it appears on a long press inside the text and follows the finger, not the caret.
|
|
1226
1229
|
- **The selection menu is Android/iOS only.** Desktop keeps `re_editor`'s keyboard shortcuts.
|
|
1227
1230
|
- **Pasting with the platform's built-in shortcut/menu inside `re_editor`** still uses its own code path; the library's paste normalization applies to its own menu and toolbar.
|
|
@@ -1241,13 +1244,13 @@ flet-code-editor-dsl/
|
|
|
1241
1244
|
| Symptom | Likely cause and fix |
|
|
1242
1245
|
|---------|----------------------|
|
|
1243
1246
|
| `Unknown control: EditorRegex` / `EditorTokens` | The app is not running with the extension compiled in. Declare the library in `pyproject.toml` and run a build made with `flet build`. |
|
|
1244
|
-
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (
|
|
1245
|
-
| `TypeError` about `incremental_highlighting` | The argument
|
|
1247
|
+
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (an older release from PyPI). See [Developing and Testing Locally](#developing-and-testing-locally): use a wheel file in `dependencies`, delete `build/`, rebuild, and check `build/site-packages/flet_code_editor_dsl/__init__.py`. |
|
|
1248
|
+
| `TypeError` about `incremental_highlighting` | The argument no longer exists; `EditorRegex` always highlights per line. Remove it. |
|
|
1246
1249
|
| `FletCodeEditor` / `FletCodeField` not found | They remain as deprecated aliases of `EditorTokens` / `EditorRegex`. If you removed the aliases, use the new names. |
|
|
1247
|
-
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), the app was **rebuilt** with 0.3.
|
|
1250
|
+
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), `selection_menu_items` is not empty, the app was **rebuilt** with 0.3.2 or newer, and the app runs on Android/iOS. The menu appears when you tap the caret, long-press, or select text. |
|
|
1248
1251
|
| Pasted text does not appear | Use *Paste* from the selection menu or the toolbar (they sanitize the clipboard text). Check that the editor is not `read_only`. |
|
|
1249
1252
|
| Magnifier does not appear | It is touch-only, needs a ~0.4 s long press inside the text area, and `magnifier` must not be `False`. |
|
|
1250
|
-
| Cursor pad is missing | It lives in the toolbar:
|
|
1253
|
+
| Cursor pad is missing | It lives in the toolbar: the toolbar must be visible (automatic on Android/iOS, or `mobile_controls=True`) and `cursor_pad` must not be `False`. |
|
|
1251
1254
|
| The page does not scroll when dragging over the editor | Check `scroll_mode`. `PAGE_FIRST` (default) moves the page first; `EDITOR_ONLY` disables hand-off. The editor must be inside a vertical scrollable (`ListView`, `Column(scroll=...)`). |
|
|
1252
1255
|
| The editor is tiny | `width_level` / `height_level` default to 13 (of 30). Set `expand=True`, `width`/`height`, or levels up to 30. |
|
|
1253
1256
|
| No colors at all | `EditorTokens`: `language` is empty or not valid JSON — pass `Language(...).to_json()` (a string). `EditorRegex`: `rules` is empty or the patterns are invalid for Dart. Also check `syntax_highlighting=True`. |
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
## Table of Contents
|
|
13
13
|
|
|
14
14
|
1. [Overview](#overview)
|
|
15
|
-
2. [What's New in 0.3.
|
|
15
|
+
2. [What's New in 0.3.2 / Migration](#whats-new-in-032--migration)
|
|
16
16
|
3. [Features](#features)
|
|
17
17
|
4. [Requirements](#requirements)
|
|
18
18
|
5. [Installation](#installation)
|
|
@@ -84,9 +84,9 @@ lang = ce.Language(
|
|
|
84
84
|
|
|
85
85
|
and hand `lang.to_json()` to `EditorTokens`.
|
|
86
86
|
|
|
87
|
-
## What's New in 0.3.
|
|
87
|
+
## What's New in 0.3.2 / Migration
|
|
88
88
|
|
|
89
|
-
### 0.3.
|
|
89
|
+
### 0.3.2
|
|
90
90
|
|
|
91
91
|
| Change | Details |
|
|
92
92
|
|--------|---------|
|
|
@@ -96,6 +96,8 @@ and hand `lang.to_json()` to `EditorTokens`.
|
|
|
96
96
|
| **Touch support** | New selection menu at the caret/handles, optional toolbar and cursor pad, magnifier, `scroll_mode`. See [Mobile / Touch Features](#mobile--touch-features). |
|
|
97
97
|
| **Paste fix** | Cut/copy/paste from the new menu/toolbar read the clipboard directly and normalize line endings and control characters before inserting. |
|
|
98
98
|
| **New Dart files** | `regex_highlighter.dart` (regex engine). `code_editor.dart` is now shared by both controls. The old `src/flet_code_editor_dsl.dart` (`CodeField` widget) was deleted. |
|
|
99
|
+
| **Number literals** | `0b…` now accepts only `0`/`1` and `0o…` only `0`–`7` (before, they accepted any hex digit, so `0b1010f` was one number). `0x…` is unchanged. |
|
|
100
|
+
| **Sigils** | If the longest matching prefix has no name after it, shorter prefixes are tried next (for example `$$` and `$` defined together: a lone `$$ ` now falls back to `$`). |
|
|
99
101
|
|
|
100
102
|
Rename in your code:
|
|
101
103
|
|
|
@@ -107,11 +109,11 @@ ce.FletCodeField(rules=[...]) ce.EditorRegex(rules=[...])
|
|
|
107
109
|
|
|
108
110
|
Because the Dart side changed, **rebuild your app** after upgrading.
|
|
109
111
|
|
|
110
|
-
###
|
|
112
|
+
### Migrating from the original `CodeEditor` API
|
|
111
113
|
|
|
112
114
|
The earlier regex-based `CodeEditor` control and its `rule()` / `group()` / `pair()` helpers no longer exist.
|
|
113
115
|
|
|
114
|
-
| Original API | 0.2
|
|
116
|
+
| Original API | 0.3.2 |
|
|
115
117
|
|-------|-------|
|
|
116
118
|
| Control `CodeEditor` | `EditorTokens` (tokenizer) and `EditorRegex` (regex) |
|
|
117
119
|
| `rule()`, `group()` + `rules_json()` | `Language(words=[WordGroup(...)], strings=..., ...)` + `Language.to_json()`; `HighlightRule` list for `EditorRegex` |
|
|
@@ -165,17 +167,17 @@ version = "1.0.0"
|
|
|
165
167
|
requires-python = ">=3.10"
|
|
166
168
|
dependencies = [
|
|
167
169
|
"flet>=0.85.2",
|
|
168
|
-
"flet-code-editor-dsl>=0.3.
|
|
170
|
+
"flet-code-editor-dsl>=0.3.2",
|
|
169
171
|
]
|
|
170
172
|
```
|
|
171
173
|
|
|
172
|
-
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.
|
|
174
|
+
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.2"`. Upgrade with `pip install --upgrade flet-code-editor-dsl`.
|
|
173
175
|
|
|
174
176
|
### Option 2: GitHub
|
|
175
177
|
|
|
176
178
|
```bash
|
|
177
179
|
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git"
|
|
178
|
-
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.
|
|
180
|
+
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.2" # pinned
|
|
179
181
|
```
|
|
180
182
|
|
|
181
183
|
Inside `pyproject.toml`:
|
|
@@ -432,13 +434,13 @@ Changing the language/rules, `syntax_highlighting`, `show_errors` or `code_foldi
|
|
|
432
434
|
|
|
433
435
|
## Mobile / Touch Features
|
|
434
436
|
|
|
435
|
-
New in 0.3.
|
|
437
|
+
New in 0.3.2. They apply to both controls. Properties that take `None` mean **automatic**: enabled on Android/iOS, disabled elsewhere.
|
|
436
438
|
|
|
437
439
|
| Property | Type | Default | Description |
|
|
438
440
|
|----------|------|---------|-------------|
|
|
439
441
|
| `selection_menu` | `bool` | `True` | Show the cut/copy/paste menu at the caret and selection handles (Android/iOS only). |
|
|
440
|
-
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu. Also accepts `"undo"`, `"redo"`. |
|
|
441
|
-
| `mobile_controls` | `bool \| None` | `None` (
|
|
442
|
+
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu, in order (see `ce.DEFAULT_SELECTION_MENU_ITEMS`). Also accepts `"undo"`, `"redo"`. Unknown ids are ignored. |
|
|
443
|
+
| `mobile_controls` | `bool \| None` | `None` (auto) | Show the extra toolbar. Auto = shown on Android/iOS, hidden elsewhere; `True` / `False` force it. |
|
|
442
444
|
| `toolbar_items` | `list[str]` | all items | Toolbar buttons, see below. |
|
|
443
445
|
| `toolbar_position` | `ToolbarPosition` | `BOTTOM` | `BOTTOM` or `TOP`. |
|
|
444
446
|
| `cursor_pad` | `bool \| None` | `None` (auto) | Draggable pad inside the toolbar. Only visible when the toolbar is shown. |
|
|
@@ -461,11 +463,12 @@ ce.EditorTokens(
|
|
|
461
463
|
|
|
462
464
|
- *Cut* and *Copy* appear only when something is selected. *Cut*, *Paste*, *Undo* and *Redo* are hidden in `read_only` mode.
|
|
463
465
|
- The menu is shown on **Android and iOS only**. On desktop, the usual keyboard shortcuts apply.
|
|
464
|
-
- Set `selection_menu=False` to disable it.
|
|
466
|
+
- Set `selection_menu=False` to disable it. The menu is rebuilt every time it opens, so changing `selection_menu_items` or `read_only` at runtime takes effect immediately.
|
|
467
|
+
- It works together with the optional toolbar: both use the same cut/copy/paste implementation (see [Paste behavior](#paste-behavior)).
|
|
465
468
|
|
|
466
469
|
### Extra toolbar and cursor pad
|
|
467
470
|
|
|
468
|
-
An
|
|
471
|
+
An extra bar next to the editor (arrows, undo/redo, home/end, tab, cursor pad). With the default `mobile_controls=None` it is **shown automatically on Android/iOS** and hidden on desktop; pass `True` or `False` to force it:
|
|
469
472
|
|
|
470
473
|
```python
|
|
471
474
|
ce.EditorTokens(
|
|
@@ -627,7 +630,7 @@ sigils=[ce.Sigil("$", "#9CDCFE"), ce.Sigil("@", "#4FC1FF"), ce.Sigil("%", "#D7BA
|
|
|
627
630
|
|
|
628
631
|
### Numbers, operators, punctuation, identifiers
|
|
629
632
|
|
|
630
|
-
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F
|
|
633
|
+
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F` hex, `0b1010` binary, `0o755` octal; each prefix accepts only its own digits and `_`). A number ends where it ends: `10px` is the number `10` followed by the identifier `px`. Identifiers cannot start with a digit. Set `numbers=False` if digits should not be treated specially.
|
|
631
634
|
|
|
632
635
|
**Operators** — each character in `Language.operators` is an operator character; a *run* of operator characters (`==`, `<=`, `&&`) becomes **one** token with `TokenColors.operator`.
|
|
633
636
|
|
|
@@ -698,7 +701,7 @@ errors=ce.ErrorRules(
|
|
|
698
701
|
)
|
|
699
702
|
```
|
|
700
703
|
|
|
701
|
-
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
704
|
+
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Not allowed: goto*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
702
705
|
|
|
703
706
|
### `FoldRule` and `fold_by_indent` (code folding)
|
|
704
707
|
|
|
@@ -1073,7 +1076,7 @@ page.add(
|
|
|
1073
1076
|
| Change | Rebuild needed? |
|
|
1074
1077
|
|--------|-----------------|
|
|
1075
1078
|
| Editing Python code, `value`, `language` / `Language(...)`, `rules`, colors, fonts, flags, sizes, layout, mobile options | No — sent to the client at runtime. |
|
|
1076
|
-
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example
|
|
1079
|
+
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example when upgrading to 0.3.2) | **Yes** |
|
|
1077
1080
|
| Upgrading Flet itself to a new major/minor version | Yes |
|
|
1078
1081
|
| Adding or removing other Flet extensions | Yes |
|
|
1079
1082
|
|
|
@@ -1120,7 +1123,7 @@ To test the library **before publishing it**:
|
|
|
1120
1123
|
```toml
|
|
1121
1124
|
dependencies = [
|
|
1122
1125
|
"flet>=0.85.2",
|
|
1123
|
-
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.
|
|
1126
|
+
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.2-py3-none-any.whl",
|
|
1124
1127
|
]
|
|
1125
1128
|
```
|
|
1126
1129
|
|
|
@@ -1174,7 +1177,7 @@ flet-code-editor-dsl/
|
|
|
1174
1177
|
├── __init__.py
|
|
1175
1178
|
└── flet_code_editor_dsl/
|
|
1176
1179
|
├── __init__.py
|
|
1177
|
-
├── pubspec.yaml # Flutter package (v0.3.
|
|
1180
|
+
├── pubspec.yaml # Flutter package (v0.3.2)
|
|
1178
1181
|
└── lib/
|
|
1179
1182
|
├── flet_code_editor_dsl.dart # Exports Extension
|
|
1180
1183
|
└── src/
|
|
@@ -1208,7 +1211,7 @@ flet-code-editor-dsl/
|
|
|
1208
1211
|
|
|
1209
1212
|
## Known Limitations
|
|
1210
1213
|
|
|
1211
|
-
- **Touch features are new in 0.3.
|
|
1214
|
+
- **Touch features are new in 0.3.2** and have had limited testing on real devices; please report problems with your device, OS version and Flet version.
|
|
1212
1215
|
- **The magnifier does not follow the selection handles** (they are owned by `re_editor`); it appears on a long press inside the text and follows the finger, not the caret.
|
|
1213
1216
|
- **The selection menu is Android/iOS only.** Desktop keeps `re_editor`'s keyboard shortcuts.
|
|
1214
1217
|
- **Pasting with the platform's built-in shortcut/menu inside `re_editor`** still uses its own code path; the library's paste normalization applies to its own menu and toolbar.
|
|
@@ -1228,13 +1231,13 @@ flet-code-editor-dsl/
|
|
|
1228
1231
|
| Symptom | Likely cause and fix |
|
|
1229
1232
|
|---------|----------------------|
|
|
1230
1233
|
| `Unknown control: EditorRegex` / `EditorTokens` | The app is not running with the extension compiled in. Declare the library in `pyproject.toml` and run a build made with `flet build`. |
|
|
1231
|
-
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (
|
|
1232
|
-
| `TypeError` about `incremental_highlighting` | The argument
|
|
1234
|
+
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (an older release from PyPI). See [Developing and Testing Locally](#developing-and-testing-locally): use a wheel file in `dependencies`, delete `build/`, rebuild, and check `build/site-packages/flet_code_editor_dsl/__init__.py`. |
|
|
1235
|
+
| `TypeError` about `incremental_highlighting` | The argument no longer exists; `EditorRegex` always highlights per line. Remove it. |
|
|
1233
1236
|
| `FletCodeEditor` / `FletCodeField` not found | They remain as deprecated aliases of `EditorTokens` / `EditorRegex`. If you removed the aliases, use the new names. |
|
|
1234
|
-
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), the app was **rebuilt** with 0.3.
|
|
1237
|
+
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), `selection_menu_items` is not empty, the app was **rebuilt** with 0.3.2 or newer, and the app runs on Android/iOS. The menu appears when you tap the caret, long-press, or select text. |
|
|
1235
1238
|
| Pasted text does not appear | Use *Paste* from the selection menu or the toolbar (they sanitize the clipboard text). Check that the editor is not `read_only`. |
|
|
1236
1239
|
| Magnifier does not appear | It is touch-only, needs a ~0.4 s long press inside the text area, and `magnifier` must not be `False`. |
|
|
1237
|
-
| Cursor pad is missing | It lives in the toolbar:
|
|
1240
|
+
| Cursor pad is missing | It lives in the toolbar: the toolbar must be visible (automatic on Android/iOS, or `mobile_controls=True`) and `cursor_pad` must not be `False`. |
|
|
1238
1241
|
| The page does not scroll when dragging over the editor | Check `scroll_mode`. `PAGE_FIRST` (default) moves the page first; `EDITOR_ONLY` disables hand-off. The editor must be inside a vertical scrollable (`ListView`, `Column(scroll=...)`). |
|
|
1239
1242
|
| The editor is tiny | `width_level` / `height_level` default to 13 (of 30). Set `expand=True`, `width`/`height`, or levels up to 30. |
|
|
1240
1243
|
| No colors at all | `EditorTokens`: `language` is empty or not valid JSON — pass `Language(...).to_json()` (a string). `EditorRegex`: `rules` is empty or the patterns are invalid for Dart. Also check `syntax_highlighting=True`. |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "flet-code-editor-dsl"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.2"
|
|
8
8
|
description = "Flet code editors with syntax highlighting: EditorTokens (tokenizer) and EditorRegex (regex)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
{flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl/__init__.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from flet_code_editor_dsl.flet_code_editor_dsl import (
|
|
2
|
+
DEFAULT_SELECTION_MENU_ITEMS,
|
|
2
3
|
DEFAULT_TOOLBAR_ITEMS,
|
|
3
4
|
EditorRegex,
|
|
4
5
|
EditorTokens,
|
|
@@ -27,7 +28,8 @@ FletCodeField = EditorRegex
|
|
|
27
28
|
__all__ = [
|
|
28
29
|
"EditorRegex", "EditorTokens",
|
|
29
30
|
"HighlightRule", "ErrorPattern",
|
|
30
|
-
"VerticalMode", "ScrollMode", "ToolbarPosition",
|
|
31
|
+
"VerticalMode", "ScrollMode", "ToolbarPosition",
|
|
32
|
+
"DEFAULT_TOOLBAR_ITEMS", "DEFAULT_SELECTION_MENU_ITEMS",
|
|
31
33
|
"Language", "WordGroup", "StringRule", "BlockComment", "Sigil",
|
|
32
34
|
"TokenColors", "FoldRule", "ErrorRules", "BracketPair",
|
|
33
35
|
"FletCodeEditor", "FletCodeField",
|
|
@@ -37,6 +37,9 @@ class ToolbarPosition(str, Enum):
|
|
|
37
37
|
TOP = "top"
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
# Buttons of the floating selection menu (Android/iOS). Also accepted: "undo", "redo".
|
|
41
|
+
DEFAULT_SELECTION_MENU_ITEMS = ["cut", "copy", "paste", "select_all"]
|
|
42
|
+
|
|
40
43
|
DEFAULT_TOOLBAR_ITEMS = [
|
|
41
44
|
"undo", "redo", "cut", "copy", "paste", "select_all", "select_mode",
|
|
42
45
|
"left", "right", "up", "down", "home", "end", "tab",
|
|
@@ -81,6 +84,8 @@ class EditorRegex(ft.LayoutControl):
|
|
|
81
84
|
debounce_ms: int = 150
|
|
82
85
|
|
|
83
86
|
# --- mobile (None = automatic: on for Android/iOS, off elsewhere) ---
|
|
87
|
+
selection_menu: bool = True # floating cut/copy/paste menu at the caret (Android/iOS)
|
|
88
|
+
selection_menu_items: list[str] = field(default_factory=lambda: list(DEFAULT_SELECTION_MENU_ITEMS))
|
|
84
89
|
mobile_controls: bool | None = None # toolbar: cut/copy/paste/undo/arrows...
|
|
85
90
|
toolbar_items: list[str] = field(default_factory=lambda: list(DEFAULT_TOOLBAR_ITEMS))
|
|
86
91
|
toolbar_position: ToolbarPosition = ToolbarPosition.BOTTOM
|
|
@@ -125,6 +130,8 @@ class EditorTokens(ft.LayoutControl):
|
|
|
125
130
|
debounce_ms: int = 150
|
|
126
131
|
|
|
127
132
|
# --- mobile ---
|
|
133
|
+
selection_menu: bool = True
|
|
134
|
+
selection_menu_items: list[str] = field(default_factory=lambda: list(DEFAULT_SELECTION_MENU_ITEMS))
|
|
128
135
|
mobile_controls: bool | None = None
|
|
129
136
|
toolbar_items: list[str] = field(default_factory=lambda: list(DEFAULT_TOOLBAR_ITEMS))
|
|
130
137
|
toolbar_position: ToolbarPosition = ToolbarPosition.BOTTOM
|
{flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2/src/flet_code_editor_dsl.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-code-editor-dsl
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Flet code editors with syntax highlighting: EditorTokens (tokenizer) and EditorRegex (regex)
|
|
5
5
|
Author-email: obgwew <obgwew@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -25,7 +25,7 @@ Dynamic: license-file
|
|
|
25
25
|
## Table of Contents
|
|
26
26
|
|
|
27
27
|
1. [Overview](#overview)
|
|
28
|
-
2. [What's New in 0.3.
|
|
28
|
+
2. [What's New in 0.3.2 / Migration](#whats-new-in-032--migration)
|
|
29
29
|
3. [Features](#features)
|
|
30
30
|
4. [Requirements](#requirements)
|
|
31
31
|
5. [Installation](#installation)
|
|
@@ -97,9 +97,9 @@ lang = ce.Language(
|
|
|
97
97
|
|
|
98
98
|
and hand `lang.to_json()` to `EditorTokens`.
|
|
99
99
|
|
|
100
|
-
## What's New in 0.3.
|
|
100
|
+
## What's New in 0.3.2 / Migration
|
|
101
101
|
|
|
102
|
-
### 0.3.
|
|
102
|
+
### 0.3.2
|
|
103
103
|
|
|
104
104
|
| Change | Details |
|
|
105
105
|
|--------|---------|
|
|
@@ -109,6 +109,8 @@ and hand `lang.to_json()` to `EditorTokens`.
|
|
|
109
109
|
| **Touch support** | New selection menu at the caret/handles, optional toolbar and cursor pad, magnifier, `scroll_mode`. See [Mobile / Touch Features](#mobile--touch-features). |
|
|
110
110
|
| **Paste fix** | Cut/copy/paste from the new menu/toolbar read the clipboard directly and normalize line endings and control characters before inserting. |
|
|
111
111
|
| **New Dart files** | `regex_highlighter.dart` (regex engine). `code_editor.dart` is now shared by both controls. The old `src/flet_code_editor_dsl.dart` (`CodeField` widget) was deleted. |
|
|
112
|
+
| **Number literals** | `0b…` now accepts only `0`/`1` and `0o…` only `0`–`7` (before, they accepted any hex digit, so `0b1010f` was one number). `0x…` is unchanged. |
|
|
113
|
+
| **Sigils** | If the longest matching prefix has no name after it, shorter prefixes are tried next (for example `$$` and `$` defined together: a lone `$$ ` now falls back to `$`). |
|
|
112
114
|
|
|
113
115
|
Rename in your code:
|
|
114
116
|
|
|
@@ -120,11 +122,11 @@ ce.FletCodeField(rules=[...]) ce.EditorRegex(rules=[...])
|
|
|
120
122
|
|
|
121
123
|
Because the Dart side changed, **rebuild your app** after upgrading.
|
|
122
124
|
|
|
123
|
-
###
|
|
125
|
+
### Migrating from the original `CodeEditor` API
|
|
124
126
|
|
|
125
127
|
The earlier regex-based `CodeEditor` control and its `rule()` / `group()` / `pair()` helpers no longer exist.
|
|
126
128
|
|
|
127
|
-
| Original API | 0.2
|
|
129
|
+
| Original API | 0.3.2 |
|
|
128
130
|
|-------|-------|
|
|
129
131
|
| Control `CodeEditor` | `EditorTokens` (tokenizer) and `EditorRegex` (regex) |
|
|
130
132
|
| `rule()`, `group()` + `rules_json()` | `Language(words=[WordGroup(...)], strings=..., ...)` + `Language.to_json()`; `HighlightRule` list for `EditorRegex` |
|
|
@@ -178,17 +180,17 @@ version = "1.0.0"
|
|
|
178
180
|
requires-python = ">=3.10"
|
|
179
181
|
dependencies = [
|
|
180
182
|
"flet>=0.85.2",
|
|
181
|
-
"flet-code-editor-dsl>=0.3.
|
|
183
|
+
"flet-code-editor-dsl>=0.3.2",
|
|
182
184
|
]
|
|
183
185
|
```
|
|
184
186
|
|
|
185
|
-
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.
|
|
187
|
+
Pin an exact version for reproducible builds: `"flet-code-editor-dsl==0.3.2"`. Upgrade with `pip install --upgrade flet-code-editor-dsl`.
|
|
186
188
|
|
|
187
189
|
### Option 2: GitHub
|
|
188
190
|
|
|
189
191
|
```bash
|
|
190
192
|
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git"
|
|
191
|
-
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.
|
|
193
|
+
pip install "git+https://github.com/obgwew/flet-code-editor-dsl.git@v0.3.2" # pinned
|
|
192
194
|
```
|
|
193
195
|
|
|
194
196
|
Inside `pyproject.toml`:
|
|
@@ -445,13 +447,13 @@ Changing the language/rules, `syntax_highlighting`, `show_errors` or `code_foldi
|
|
|
445
447
|
|
|
446
448
|
## Mobile / Touch Features
|
|
447
449
|
|
|
448
|
-
New in 0.3.
|
|
450
|
+
New in 0.3.2. They apply to both controls. Properties that take `None` mean **automatic**: enabled on Android/iOS, disabled elsewhere.
|
|
449
451
|
|
|
450
452
|
| Property | Type | Default | Description |
|
|
451
453
|
|----------|------|---------|-------------|
|
|
452
454
|
| `selection_menu` | `bool` | `True` | Show the cut/copy/paste menu at the caret and selection handles (Android/iOS only). |
|
|
453
|
-
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu. Also accepts `"undo"`, `"redo"`. |
|
|
454
|
-
| `mobile_controls` | `bool \| None` | `None` (
|
|
455
|
+
| `selection_menu_items` | `list[str]` | `["cut","copy","paste","select_all"]` | Buttons of that menu, in order (see `ce.DEFAULT_SELECTION_MENU_ITEMS`). Also accepts `"undo"`, `"redo"`. Unknown ids are ignored. |
|
|
456
|
+
| `mobile_controls` | `bool \| None` | `None` (auto) | Show the extra toolbar. Auto = shown on Android/iOS, hidden elsewhere; `True` / `False` force it. |
|
|
455
457
|
| `toolbar_items` | `list[str]` | all items | Toolbar buttons, see below. |
|
|
456
458
|
| `toolbar_position` | `ToolbarPosition` | `BOTTOM` | `BOTTOM` or `TOP`. |
|
|
457
459
|
| `cursor_pad` | `bool \| None` | `None` (auto) | Draggable pad inside the toolbar. Only visible when the toolbar is shown. |
|
|
@@ -474,11 +476,12 @@ ce.EditorTokens(
|
|
|
474
476
|
|
|
475
477
|
- *Cut* and *Copy* appear only when something is selected. *Cut*, *Paste*, *Undo* and *Redo* are hidden in `read_only` mode.
|
|
476
478
|
- The menu is shown on **Android and iOS only**. On desktop, the usual keyboard shortcuts apply.
|
|
477
|
-
- Set `selection_menu=False` to disable it.
|
|
479
|
+
- Set `selection_menu=False` to disable it. The menu is rebuilt every time it opens, so changing `selection_menu_items` or `read_only` at runtime takes effect immediately.
|
|
480
|
+
- It works together with the optional toolbar: both use the same cut/copy/paste implementation (see [Paste behavior](#paste-behavior)).
|
|
478
481
|
|
|
479
482
|
### Extra toolbar and cursor pad
|
|
480
483
|
|
|
481
|
-
An
|
|
484
|
+
An extra bar next to the editor (arrows, undo/redo, home/end, tab, cursor pad). With the default `mobile_controls=None` it is **shown automatically on Android/iOS** and hidden on desktop; pass `True` or `False` to force it:
|
|
482
485
|
|
|
483
486
|
```python
|
|
484
487
|
ce.EditorTokens(
|
|
@@ -640,7 +643,7 @@ sigils=[ce.Sigil("$", "#9CDCFE"), ce.Sigil("@", "#4FC1FF"), ce.Sigil("%", "#D7BA
|
|
|
640
643
|
|
|
641
644
|
### Numbers, operators, punctuation, identifiers
|
|
642
645
|
|
|
643
|
-
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F
|
|
646
|
+
**Numbers** (`numbers=True`): integers and decimals (`42`, `3.14`, `.5`), digit separators (`1_000_000`), exponents (`1e10`, `2.5E-3`), prefixed literals (`0x1F` hex, `0b1010` binary, `0o755` octal; each prefix accepts only its own digits and `_`). A number ends where it ends: `10px` is the number `10` followed by the identifier `px`. Identifiers cannot start with a digit. Set `numbers=False` if digits should not be treated specially.
|
|
644
647
|
|
|
645
648
|
**Operators** — each character in `Language.operators` is an operator character; a *run* of operator characters (`==`, `<=`, `&&`) becomes **one** token with `TokenColors.operator`.
|
|
646
649
|
|
|
@@ -711,7 +714,7 @@ errors=ce.ErrorRules(
|
|
|
711
714
|
)
|
|
712
715
|
```
|
|
713
716
|
|
|
714
|
-
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
717
|
+
> The lexer builds a message for each error (*Unterminated string*, *Unknown word: foo*, *Not allowed: goto*, *Unmatched ')'*, *Unclosed '('*), but the editor only draws the underline; messages are not shown as tooltips yet. Brackets spanning several lines are **not** matched across lines; for a language where `{` and `}` regularly sit on different lines, leave the `{}` pair out.
|
|
715
718
|
|
|
716
719
|
### `FoldRule` and `fold_by_indent` (code folding)
|
|
717
720
|
|
|
@@ -1086,7 +1089,7 @@ page.add(
|
|
|
1086
1089
|
| Change | Rebuild needed? |
|
|
1087
1090
|
|--------|-----------------|
|
|
1088
1091
|
| Editing Python code, `value`, `language` / `Language(...)`, `rules`, colors, fonts, flags, sizes, layout, mobile options | No — sent to the client at runtime. |
|
|
1089
|
-
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example
|
|
1092
|
+
| Updating `flet-code-editor-dsl` to a version whose Dart code changed (for example when upgrading to 0.3.2) | **Yes** |
|
|
1090
1093
|
| Upgrading Flet itself to a new major/minor version | Yes |
|
|
1091
1094
|
| Adding or removing other Flet extensions | Yes |
|
|
1092
1095
|
|
|
@@ -1133,7 +1136,7 @@ To test the library **before publishing it**:
|
|
|
1133
1136
|
```toml
|
|
1134
1137
|
dependencies = [
|
|
1135
1138
|
"flet>=0.85.2",
|
|
1136
|
-
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.
|
|
1139
|
+
"flet-code-editor-dsl @ file:///C:/path/to/repo/dist/flet_code_editor_dsl-0.3.2-py3-none-any.whl",
|
|
1137
1140
|
]
|
|
1138
1141
|
```
|
|
1139
1142
|
|
|
@@ -1187,7 +1190,7 @@ flet-code-editor-dsl/
|
|
|
1187
1190
|
├── __init__.py
|
|
1188
1191
|
└── flet_code_editor_dsl/
|
|
1189
1192
|
├── __init__.py
|
|
1190
|
-
├── pubspec.yaml # Flutter package (v0.3.
|
|
1193
|
+
├── pubspec.yaml # Flutter package (v0.3.2)
|
|
1191
1194
|
└── lib/
|
|
1192
1195
|
├── flet_code_editor_dsl.dart # Exports Extension
|
|
1193
1196
|
└── src/
|
|
@@ -1221,7 +1224,7 @@ flet-code-editor-dsl/
|
|
|
1221
1224
|
|
|
1222
1225
|
## Known Limitations
|
|
1223
1226
|
|
|
1224
|
-
- **Touch features are new in 0.3.
|
|
1227
|
+
- **Touch features are new in 0.3.2** and have had limited testing on real devices; please report problems with your device, OS version and Flet version.
|
|
1225
1228
|
- **The magnifier does not follow the selection handles** (they are owned by `re_editor`); it appears on a long press inside the text and follows the finger, not the caret.
|
|
1226
1229
|
- **The selection menu is Android/iOS only.** Desktop keeps `re_editor`'s keyboard shortcuts.
|
|
1227
1230
|
- **Pasting with the platform's built-in shortcut/menu inside `re_editor`** still uses its own code path; the library's paste normalization applies to its own menu and toolbar.
|
|
@@ -1241,13 +1244,13 @@ flet-code-editor-dsl/
|
|
|
1241
1244
|
| Symptom | Likely cause and fix |
|
|
1242
1245
|
|---------|----------------------|
|
|
1243
1246
|
| `Unknown control: EditorRegex` / `EditorTokens` | The app is not running with the extension compiled in. Declare the library in `pyproject.toml` and run a build made with `flet build`. |
|
|
1244
|
-
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (
|
|
1245
|
-
| `TypeError` about `incremental_highlighting` | The argument
|
|
1247
|
+
| `ImportError: cannot import name 'EditorRegex'` in the built app | The build packaged an older version (an older release from PyPI). See [Developing and Testing Locally](#developing-and-testing-locally): use a wheel file in `dependencies`, delete `build/`, rebuild, and check `build/site-packages/flet_code_editor_dsl/__init__.py`. |
|
|
1248
|
+
| `TypeError` about `incremental_highlighting` | The argument no longer exists; `EditorRegex` always highlights per line. Remove it. |
|
|
1246
1249
|
| `FletCodeEditor` / `FletCodeField` not found | They remain as deprecated aliases of `EditorTokens` / `EditorRegex`. If you removed the aliases, use the new names. |
|
|
1247
|
-
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), the app was **rebuilt** with 0.3.
|
|
1250
|
+
| No cut/copy/paste menu on the phone | Make sure `selection_menu=True` (default), `selection_menu_items` is not empty, the app was **rebuilt** with 0.3.2 or newer, and the app runs on Android/iOS. The menu appears when you tap the caret, long-press, or select text. |
|
|
1248
1251
|
| Pasted text does not appear | Use *Paste* from the selection menu or the toolbar (they sanitize the clipboard text). Check that the editor is not `read_only`. |
|
|
1249
1252
|
| Magnifier does not appear | It is touch-only, needs a ~0.4 s long press inside the text area, and `magnifier` must not be `False`. |
|
|
1250
|
-
| Cursor pad is missing | It lives in the toolbar:
|
|
1253
|
+
| Cursor pad is missing | It lives in the toolbar: the toolbar must be visible (automatic on Android/iOS, or `mobile_controls=True`) and `cursor_pad` must not be `False`. |
|
|
1251
1254
|
| The page does not scroll when dragging over the editor | Check `scroll_mode`. `PAGE_FIRST` (default) moves the page first; `EDITOR_ONLY` disables hand-off. The editor must be inside a vertical scrollable (`ListView`, `Column(scroll=...)`). |
|
|
1252
1255
|
| The editor is tiny | `width_level` / `height_level` default to 13 (of 30). Set `expand=True`, `width`/`height`, or levels up to 30. |
|
|
1253
1256
|
| No colors at all | `EditorTokens`: `language` is empty or not valid JSON — pass `Language(...).to_json()` (a string). `EditorRegex`: `rules` is empty or the patterns are invalid for Dart. Also check `syntax_highlighting=True`. |
|
|
@@ -83,6 +83,8 @@ const List<String> _defaultToolbar = [
|
|
|
83
83
|
"left", "right", "up", "down", "home", "end", "tab",
|
|
84
84
|
];
|
|
85
85
|
|
|
86
|
+
const List<String> _defaultSelectionMenu = ["cut", "copy", "paste", "select_all"];
|
|
87
|
+
|
|
86
88
|
class _FletEditorControlState extends State<FletEditorControl> {
|
|
87
89
|
late final CodeLineEditingController _controller;
|
|
88
90
|
Timer? _debounce;
|
|
@@ -111,6 +113,66 @@ class _FletEditorControlState extends State<FletEditorControl> {
|
|
|
111
113
|
int? _pointer;
|
|
112
114
|
final ValueNotifier<Offset?> _magnifierAt = ValueNotifier<Offset?>(null);
|
|
113
115
|
|
|
116
|
+
// Floating cut/copy/paste menu (re_editor only shows one when it is given a
|
|
117
|
+
// toolbar controller). Only used on Android/iOS.
|
|
118
|
+
late final MobileSelectionToolbarController _menuController =
|
|
119
|
+
MobileSelectionToolbarController(builder: _menuBuilder);
|
|
120
|
+
|
|
121
|
+
Widget _menuBuilder({
|
|
122
|
+
required BuildContext context,
|
|
123
|
+
required TextSelectionToolbarAnchors anchors,
|
|
124
|
+
required CodeLineEditingController controller,
|
|
125
|
+
required VoidCallback onDismiss,
|
|
126
|
+
required VoidCallback onRefresh,
|
|
127
|
+
}) {
|
|
128
|
+
final readOnly = widget.control.getBool("read_only", false)!;
|
|
129
|
+
final raw = widget.control.get("selection_menu_items");
|
|
130
|
+
final ids = raw is List
|
|
131
|
+
? [for (final i in raw) i.toString()]
|
|
132
|
+
: _defaultSelectionMenu;
|
|
133
|
+
final loc = MaterialLocalizations.of(context);
|
|
134
|
+
final hasSelection = controller.selectedText.isNotEmpty;
|
|
135
|
+
|
|
136
|
+
final items = <ContextMenuButtonItem>[];
|
|
137
|
+
void add(String label, VoidCallback run) {
|
|
138
|
+
items.add(ContextMenuButtonItem(
|
|
139
|
+
label: label,
|
|
140
|
+
onPressed: () {
|
|
141
|
+
run();
|
|
142
|
+
onDismiss();
|
|
143
|
+
},
|
|
144
|
+
));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
for (final id in ids) {
|
|
148
|
+
switch (id) {
|
|
149
|
+
case "cut":
|
|
150
|
+
if (!readOnly && hasSelection) add(loc.cutButtonLabel, () => _cut());
|
|
151
|
+
break;
|
|
152
|
+
case "copy":
|
|
153
|
+
if (hasSelection) add(loc.copyButtonLabel, () => _copy());
|
|
154
|
+
break;
|
|
155
|
+
case "paste":
|
|
156
|
+
if (!readOnly) add(loc.pasteButtonLabel, () => _paste());
|
|
157
|
+
break;
|
|
158
|
+
case "select_all":
|
|
159
|
+
add(loc.selectAllButtonLabel, () => _controller.selectAll());
|
|
160
|
+
break;
|
|
161
|
+
case "undo":
|
|
162
|
+
if (!readOnly) add("Undo", () => _controller.undo());
|
|
163
|
+
break;
|
|
164
|
+
case "redo":
|
|
165
|
+
if (!readOnly) add("Redo", () => _controller.redo());
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (items.isEmpty) return const SizedBox.shrink();
|
|
170
|
+
return AdaptiveTextSelectionToolbar.buttonItems(
|
|
171
|
+
anchors: anchors,
|
|
172
|
+
buttonItems: items,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
114
176
|
bool get _isMobilePlatform =>
|
|
115
177
|
defaultTargetPlatform == TargetPlatform.android ||
|
|
116
178
|
defaultTargetPlatform == TargetPlatform.iOS;
|
|
@@ -132,6 +194,7 @@ class _FletEditorControlState extends State<FletEditorControl> {
|
|
|
132
194
|
void dispose() {
|
|
133
195
|
_debounce?.cancel();
|
|
134
196
|
_lpTimer?.cancel();
|
|
197
|
+
_menuController.hide(context);
|
|
135
198
|
_magnifierAt.dispose();
|
|
136
199
|
_controller.removeListener(_onControllerChanged);
|
|
137
200
|
_controller.dispose();
|
|
@@ -576,6 +639,7 @@ class _FletEditorControlState extends State<FletEditorControl> {
|
|
|
576
639
|
? [for (final i in itemsRaw) i.toString()]
|
|
577
640
|
: _defaultToolbar;
|
|
578
641
|
final scrollMode = control.getString("scroll_mode", "page_first")!;
|
|
642
|
+
final showMenu = mobile && control.getBool("selection_menu", true)!;
|
|
579
643
|
|
|
580
644
|
Widget editor = CodeEditor(
|
|
581
645
|
key: ValueKey("editor_$_epoch"),
|
|
@@ -584,6 +648,7 @@ class _FletEditorControlState extends State<FletEditorControl> {
|
|
|
584
648
|
wordWrap: wrap,
|
|
585
649
|
padding: const EdgeInsets.all(4),
|
|
586
650
|
onChanged: _handleChanged,
|
|
651
|
+
toolbarController: showMenu ? _menuController : null,
|
|
587
652
|
chunkAnalyzer: _chunkAnalyzer,
|
|
588
653
|
style: CodeEditorStyle(
|
|
589
654
|
fontFamily: fontFamily,
|
|
@@ -460,8 +460,8 @@ class CodeLanguage {
|
|
|
460
460
|
add(pos, e, s.color);
|
|
461
461
|
pos = e;
|
|
462
462
|
matched = true;
|
|
463
|
+
break;
|
|
463
464
|
}
|
|
464
|
-
break;
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
467
|
if (matched) continue;
|
|
@@ -476,7 +476,16 @@ class CodeLanguage {
|
|
|
476
476
|
(next == 120 || next == 88 || next == 98 || next == 66 ||
|
|
477
477
|
next == 111 || next == 79)) {
|
|
478
478
|
e += 2;
|
|
479
|
-
|
|
479
|
+
final isHexLit = next == 120 || next == 88;
|
|
480
|
+
final isBinLit = next == 98 || next == 66;
|
|
481
|
+
bool digitOk(int c) =>
|
|
482
|
+
c == 95 ||
|
|
483
|
+
(isHexLit
|
|
484
|
+
? _isHex(c)
|
|
485
|
+
: isBinLit
|
|
486
|
+
? (c == 48 || c == 49)
|
|
487
|
+
: (c >= 48 && c <= 55));
|
|
488
|
+
while (e < n && digitOk(line.codeUnitAt(e))) {
|
|
480
489
|
e++;
|
|
481
490
|
}
|
|
482
491
|
} else {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flet_code_editor_dsl-0.3.1 → flet_code_editor_dsl-0.3.2}/src/flet_code_editor_dsl/language.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|