Akvelon is excited to announce that we have launched our Flutter Code Editor – an open source customizable and feature-rich code editor widget for Flutter applications. Our Flutter Code Editor makes it much easier to add code editing capabilities in Flutter applications, and can be used in any app instead of the ordinary TextField widget. It currently supports:
- Syntax highlighting for over 100 languages
- Real-time highlighting of unmatched parentheses, brackets, and braces
- Autocompletion
- Auto-identation, indentation settings, and line numbers
- Code folding for Dart, Go, Java, Python, and Scala
- Read-only sections
- Shortcuts
- Themes
- API to highlight errors and warnings e.g. reported by your custom backend
At Akvelon, we first developed this editor to use it in a code playground that we developed for Apache Beam.
Check it out here to try the editor live.
Basic Usage
See the full runnable example here.
Languages
Syntax Highlighting
Flutter Code Editor supports over a hundred languages, relying on the highlight package for parsing code.
To select a language, use a corresponding variable:
Language can be dynamically changed on a controller:
Code Blocks Folding
Flutter Code Editor can detect and fold code blocks. Code blocks folding is supported for the following languages:
- Dart
- Go
- Java
- Python
- Scala
Code blocks folding may support other languages in experimental mode.
Code Analysis
The editor supports pluggable analyzers to highlight errors and show error messages:
We ship the following analyzers:
DefaultLocalAnalyzer
highlights unmatched pair characters for supported languages. It works on the client locally, and is selected by default onCodeController
if no other analyzer is specified.DartPadAnalyzer
for Dart language, calls upon the DartPad backend for analysis.
For other languages, you can write custom analyzers that access your backend. See the code for DartPadAnalyzer
for the implementation example.
To set the analyzer, call any of the following:
Note: Code analysis is an experimental feature. We may introduce breaking changes to Analyzer
subclasses without following the semver contract. If you only use the analyzers we ship, then this will not affect you.
Themes
Custom Themes
To use a custom theme, create a map of styles under the pre-defined class names — see this example.
Hiding Line Numbers, Errors, and Folding Handles
A lot of styling can be tuned with a GutterStyle
object passed to a CodeField
widget. See this example that dynamically changes the properties listed here.
If you want to hide the entire gutter, use GutterStyle.none
constant instead:
Accessing the Text
CodeController
extends Flutter's built-in TextEditingController
and is immediately usable as one. However, code folding and other features have impact on built-in properties:
text
returns and sets the visible text. If any code is folded, it will not be returned.value
returns and sets theTextEditingValue
with the visible text and selection. If any code is folded, it will not be returned.fullText
returns and sets the entire text, including any folded blocks and hidden service comments (see below).
Named Sections
To manipulate parts of the source code, Flutter Code Editor supports named sections. They are defined in the code by adding tags that Flutter Code Editor recognizes.
To define a named section in your source code, add comments to tag the start and the end of the section:
- Add comment
[START section_name]
to tag the beginning of the section - Add comment
[END section_name]
to tag the end of the section
Here is an example to define a named section section1
:
To process named sections in the Flutter Code Editor, pass the named section parser to the controller:
The example above creates a section named section1
. The built-in BracketsStartEndNamedSectionParser
class is designed to parse sections from the code comments using the above syntax. It also hides any single-line comment that has a section tag with the above syntax, although such comments are still present in the editor's hidden state and will be revealed when copying the text.
To customize section parsing using any other syntax, use subclass AbstractNamedSectionParser
.
Read-Only Code Blocks
Flutter Code Editor allows you to define read-only code blocks. This may be useful for learning use cases when users are guided to modify certain code blocks while other code is meant to be protected from changes.
To make a named section read-only, pass a set of named sections to the controller.readOnlySectionNames
:
This locks the given sections from modifications in the Flutter Code Editor. Any non-existent section names in this set are ignored. To make the code editable again, pass an updated set to controller.readOnlySectionNames
.
When using this feature, text
and value
properties cannot be used to change the text programmatically because they have the same effect as the user input. This means that locking affects them as well.
To change a partially locked controller, set the fullText
property.
Advanced Code Blocks Folding
Folding the First Comment/License
Many code snippets contain a license as their first comment, which can distract readers. To fold the first comment, use:
This method has no effect if there is no comment starting at the first line.
Folding imports
In many languages, the editor recognizes sequential import lines and an optional package line as one foldable block. To fold such blocks:
Named sections
The editor supports folding all blocks except for specifically named sections. This helps the user focus on those sections while all source code is still there, which can be expanded and copied by the user.
To fold all blocks except those overlapping with the given named sections:
Folding Specific Blocks
To fold and unfold blocks at a given line number:
If there is no block at a given line, this has no effect.
Note: For the controller, line numbers start at 0 although the widget displays them starting at 1
.
Accessing Folded Blocks
To get the currently folded blocks, read controller.code.foldedBlocks
.
Hiding Text
The editor allows you to completely hide all code except for a specifically named section. This is useful to achieve even more focus than with folding.
To hide all the code except the given named section:
When hiding text, the full text is still preserved and available via fullText
property in the Flutter Code Editor.
Hiding text preserves line numbering, which is not possible by just showing a cropped snippet. Preserving hidden text is also useful if you later need to send the full code for further processing but still want to hide non-informative parts.
Hiding text also makes the entire editor read-only to prevent users from modifying the code, adding imports, etc. which may conflict with the hidden parts.
Only one visible section at a time is currently supported. The behavior of passing more than one section is undefined.
Autocompletion
The editor suggests words as they are typed. Suggested words are:
- All keywords of the current language
- All words already in the text
- Words set with
controller.autocompleter.setCustomWords(['word1', 'word2'])
All those words are merged into an unstructured dictionary. The editor doesn’t perform any syntax analysis, so it cannot tell if a given class really has the method the user is typing. This feature is meant to simplify typing, but should not be relied on when exploring classes and methods.
To disable autocompletion:
Shortcuts
- Indent (Tab)
- Outdent (Shift-Tab)
- Comment out (Control-/)
- Uncomment (Control-/)
What People do With This Editor
People are already using this editor in the wild. We have seen an app that uses this editor:
- to produce fancy highlighted screenshots of a code
- to record a video of code being typed and highlighted, which is cool if you record tutorials
We invite you to try Flutter Code Editor on pub.dev or directly from https://github.com/akvelon/flutter-code-editor, and we encourage you to share your feedback or report any issues you may face.
The Team
The Akvelon’s team that has developed the Flutter Code Editor is Alexey Inkin, Yestay Tastanov, Dmitry Repin, Darkhan Nausharipov, Alex Kosolapov.
About Akvelon
To get in touch with us, request a custom feature, or share about your use case – send us a message at https://akvelon.com/contact-us/.
Akvelon provides Flutter, Web, and Mobile application development services – get in touch with us to request a custom app or modernize your existing app experience!
To learn more about Akvelon’s ML, Data and Analytics, and other services visit us at Akvelon.com or check out our Blog
Alexey Inkin
Lead Flutter Developer at Akvelon