Lucy_Editor
Lucy_Editor
is a powerful lightweight text and code editor widget and a module in the Reqable project. It can be used as a simple text area or to develop a code editor with complex functions. Unlike Flutter's default TextField
component, Lucy_Editor
is specifically tailored for the display and input of multi-line text and offers the following features:
- Two-way horizontal and vertical scrolling.
- Text syntax highlighting.
- Content collapsing and expanding.
- Input hints and auto-completion.
- Search and replace.
- Custom context menu builder.
- Shortcut keys.
- Large text display and editing.
- Line numbers and focus line builder.
- Smart input.
- Improve performance.
- Support Javascript AST
- More complicate AutoComplete for Javascript
Lucy_Editor
is not a secondary encapsulation based on TextField
, but independently implements the layout, drawing, event processing, etc. It is specifically optimized for large texts, providing extremely high performance and fixed some issues of TextField
.
Lucy_Editor
offers a high degree of freedom. For example, developers can control whether to enable horizontal scrolling (word wrap), enable read-only mode, display line numbers, display content folding, define custom shortcut keys, and specify text syntax highlighting.
You can run the example
project to experience it.
Getting Started
Add the followings in pubspec.yaml
.
dependencies:
lucy_editor: ^1.0.7
Like TextField
, Lucy_Editor
uses CodeLineEditingController
as the controller. The following sample code creates the simplest editor component, which is not much different from TextField
.
Widget build(BuildContext context) {
return CodeEditor(
controller: CodeLineEditingController.fromText('Hello Reqable'),
);
}
Text Syntax Highlighting
The text highlighting of Lucy_Editor
is based on Re-Highlight and supports nearly a hundred languages and theme styles. Developers can freely choose and configure the code Highlight. The following code specifies the JSON
syntax highlighting rules and applies the Atom One Light
code coloring.
CodeEditor(
style: CodeEditorStyle(
codeTheme: CodeHighlightTheme(
languages: {
'json': CodeHighlightThemeMode(
mode: langJson
)
},
theme: atomOneLightTheme
),
),
);
Line Numbers and Fold/Unfold Markers
Lucy_Editor
supports configuring whether to display code line numbers and code folding marks, and developers can also implement display styles and layouts by themselves. The example code below shows the default style, built with indicatorBuilder
.
CodeEditor(
indicatorBuilder: (context, editingController, chunkController, notifier) {
return Row(
children: [
DefaultCodeLineNumber(
controller: editingController,
notifier: notifier,
),
DefaultCodeChunkIndicator(
width: 20,
controller: chunkController,
notifier: notifier
)
],
);
},
);
Code Folding and Unfolding Detection
By default, Lucy_Editor
will automatically detect the folding areas of {}
and []
. Developers can control whether to detect or write their own detection rules. DefaultCodeChunkAnalyzer
is the default detector. If you wish to disable detection, you can use NonCodeChunkAnalyzer
.
CodeEditor(
chunkAnalyzer: DefaultCodeChunkAnalyzer(),
);
If you want to customize it, just implement the CodeChunkAnalyzer
interface.
abstract class CodeChunkAnalyzer {
List<CodeChunk> run(CodeLines codeLines);
}
Scroll Control
Lucy_Editor
supports two-way scrolling, so two ScrollController
are used, and developers can use CodeScrollController
to construct.
CodeEditor(
scrollController: CodeScrollController(
verticalScroller: ScrollController(),
horizontalScroller: ScrollController(),
)
);
Find and Replace
Lucy_Editor
implements search and replace control logic, but does not provide a default UI. Developers need to write the UI of the search panel according to the actual situation of their own projects, and use the findBuilder
attribute to set up their own search and replace UI.
CodeEditor(
findBuilder: (context, controller, readOnly) => CodeFindPanelView(controller: controller, readOnly: readOnly),
);
The CodeFindPanelView
in the above example is implemented by the developer himself. For the detailed implementation process, please refer to the code in example
.
Context Menu
Lucy_Editor
implements the control logic of the desktop context menu and the mobile long-press selection menu, but does not provide a default UI. Developers need to implement the SelectionToolbarController
interface and setup it through toolbarController
.
CodeEditor(
toolbarController: _MyToolbarController(),
);
Shortcuts
Lucy_Editor
has the built-in default shortcut hotkeys, and developers can also use shortcutsActivatorsBuilder
to set custom shortcut hotkeys. Of course, the shortcut keys only work on the desktop.
The shortcut keys supported by Lucy_Editor
are as follows:
- Select all (Control/Command + A)
- Cut selected/current line (Control/Command + V)
- Copy selected/current line (Control/Command + C)
- Paste (Control/Command + V)
- Undo (Control/Command + Z)
- Redo (Shift + Control/Command + Z)
- Select the current line (Control/Command + L)
- Delete current line (Control/Command + D)
- Move current line (Alt + ↑/↓)
- Continuous selection (Shift + ↑/↓/←/→)
- Move cursor (↑/↓/←/→)
- Move to top/bottom of page (Control/Command + ↑/↓)
- Indent (Tab)
- Unindent (Shift + Tab)
- Comment/uncomment a single line (Control/Command + /)
- Comment/uncomment multiple lines (Shift + Control/Command + /)
- Character transpose (Control/Command + T)
- Search (Control/Command + F)
- Replace (Alt + Control/Command + F)
- Save (Control/Command + S)
Code Hints and Auto-Completion
Lucy_Editor
supports using the CodeAutocomplete
component to implement code input prompts and automatic completion. Lucy_Editor
implements basic control logic, but the code prompt content, auto-completion rules and display UI need to be defined by the developer.
CodeAutocomplete(
builder: (context, notifier, onSelected) {
// TODO
},
language: langDart,
child: CodeEditor()
);
Note that Lucy_Editor
is only a lightweight editor and does not have the IDE dynamic syntax analysis, so the code prompts and completion have many limitations. You can refer to the code in example
to implement a simple code prompt and completion.
Used By
Lucy_Editor
has been extensively practiced in the Reqable project. You are welcome to download Reqable to experience it.
License
MIT License
Sponsor
If you would like to sponsor this project, you can support us by purchasing a Reqable license.
Libraries
- jsparser
- languages/javascript
- languages/json
- languages/lib/common
- languages/lib/javascript
- languages/lib/mathematica
- languages/lib/php
- languages/lib/typescript
- lucy_editor
- parsejs/annotations
- parsejs/ast
- parsejs/charcode
- parsejs/lexer
- parsejs/noise
- parsejs/parser
- styles/a11y-dark
- styles/a11y-light
- styles/agate
- styles/all
- styles/an-old-hope
- styles/androidstudio
- styles/arduino-light
- styles/arta
- styles/ascetic
- styles/atom-one-dark
- styles/atom-one-dark-reasonable
- styles/atom-one-light
- styles/base16/apathy
- styles/base16/apprentice
- styles/base16/ashes
- styles/base16/atelier-cave
- styles/base16/atelier-cave-light
- styles/base16/atelier-dune
- styles/base16/atelier-dune-light
- styles/base16/atelier-estuary
- styles/base16/atelier-estuary-light
- styles/base16/atelier-forest
- styles/base16/atelier-forest-light
- styles/base16/atelier-heath
- styles/base16/atelier-heath-light
- styles/base16/atelier-lakeside
- styles/base16/atelier-lakeside-light
- styles/base16/atelier-plateau
- styles/base16/atelier-plateau-light
- styles/base16/atelier-savanna
- styles/base16/atelier-savanna-light
- styles/base16/atelier-seaside
- styles/base16/atelier-seaside-light
- styles/base16/atelier-sulphurpool
- styles/base16/atelier-sulphurpool-light
- styles/base16/atlas
- styles/base16/bespin
- styles/base16/black-metal
- styles/base16/black-metal-bathory
- styles/base16/black-metal-burzum
- styles/base16/black-metal-dark-funeral
- styles/base16/black-metal-gorgoroth
- styles/base16/black-metal-immortal
- styles/base16/black-metal-khold
- styles/base16/black-metal-marduk
- styles/base16/black-metal-mayhem
- styles/base16/black-metal-nile
- styles/base16/black-metal-venom
- styles/base16/brewer
- styles/base16/bright
- styles/base16/brogrammer
- styles/base16/brush-trees
- styles/base16/brush-trees-dark
- styles/base16/chalk
- styles/base16/circus
- styles/base16/classic-dark
- styles/base16/classic-light
- styles/base16/codeschool
- styles/base16/colors
- styles/base16/cupcake
- styles/base16/cupertino
- styles/base16/danqing
- styles/base16/darcula
- styles/base16/dark-violet
- styles/base16/darkmoss
- styles/base16/darktooth
- styles/base16/decaf
- styles/base16/default-dark
- styles/base16/default-light
- styles/base16/dirtysea
- styles/base16/dracula
- styles/base16/edge-dark
- styles/base16/edge-light
- styles/base16/eighties
- styles/base16/embers
- styles/base16/equilibrium-dark
- styles/base16/equilibrium-gray-dark
- styles/base16/equilibrium-gray-light
- styles/base16/equilibrium-light
- styles/base16/espresso
- styles/base16/eva
- styles/base16/eva-dim
- styles/base16/flat
- styles/base16/framer
- styles/base16/fruit-soda
- styles/base16/gigavolt
- styles/base16/github
- styles/base16/google-dark
- styles/base16/google-light
- styles/base16/grayscale-dark
- styles/base16/grayscale-light
- styles/base16/green-screen
- styles/base16/gruvbox-dark-hard
- styles/base16/gruvbox-dark-medium
- styles/base16/gruvbox-dark-pale
- styles/base16/gruvbox-dark-soft
- styles/base16/gruvbox-light-hard
- styles/base16/gruvbox-light-medium
- styles/base16/gruvbox-light-soft
- styles/base16/hardcore
- styles/base16/harmonic16-dark
- styles/base16/harmonic16-light
- styles/base16/heetch-dark
- styles/base16/heetch-light
- styles/base16/helios
- styles/base16/hopscotch
- styles/base16/horizon-dark
- styles/base16/horizon-light
- styles/base16/humanoid-dark
- styles/base16/humanoid-light
- styles/base16/ia-dark
- styles/base16/ia-light
- styles/base16/icy-dark
- styles/base16/ir-black
- styles/base16/isotope
- styles/base16/kimber
- styles/base16/london-tube
- styles/base16/macintosh
- styles/base16/marrakesh
- styles/base16/materia
- styles/base16/material
- styles/base16/material-darker
- styles/base16/material-lighter
- styles/base16/material-palenight
- styles/base16/material-vivid
- styles/base16/mellow-purple
- styles/base16/mexico-light
- styles/base16/mocha
- styles/base16/monokai
- styles/base16/nebula
- styles/base16/nord
- styles/base16/nova
- styles/base16/ocean
- styles/base16/oceanicnext
- styles/base16/one-light
- styles/base16/onedark
- styles/base16/outrun-dark
- styles/base16/papercolor-dark
- styles/base16/papercolor-light
- styles/base16/paraiso
- styles/base16/pasque
- styles/base16/phd
- styles/base16/pico
- styles/base16/pop
- styles/base16/porple
- styles/base16/qualia
- styles/base16/railscasts
- styles/base16/rebecca
- styles/base16/ros-pine
- styles/base16/ros-pine-dawn
- styles/base16/ros-pine-moon
- styles/base16/sagelight
- styles/base16/sandcastle
- styles/base16/seti-ui
- styles/base16/shapeshifter
- styles/base16/silk-dark
- styles/base16/silk-light
- styles/base16/snazzy
- styles/base16/solar-flare
- styles/base16/solar-flare-light
- styles/base16/solarized-dark
- styles/base16/solarized-light
- styles/base16/spacemacs
- styles/base16/summercamp
- styles/base16/summerfruit-dark
- styles/base16/summerfruit-light
- styles/base16/synth-midnight-terminal-dark
- styles/base16/synth-midnight-terminal-light
- styles/base16/tango
- styles/base16/tender
- styles/base16/tomorrow
- styles/base16/tomorrow-night
- styles/base16/twilight
- styles/base16/unikitty-dark
- styles/base16/unikitty-light
- styles/base16/vulcan
- styles/base16/windows-10
- styles/base16/windows-10-light
- styles/base16/windows-95
- styles/base16/windows-95-light
- styles/base16/windows-high-contrast
- styles/base16/windows-high-contrast-light
- styles/base16/windows-nt
- styles/base16/windows-nt-light
- styles/base16/woodland
- styles/base16/xcode-dusk
- styles/base16/zenburn
- styles/brown-paper
- styles/codepen-embed
- styles/color-brewer
- styles/dark
- styles/default
- styles/devibeans
- styles/docco
- styles/far
- styles/felipec
- styles/foundation
- styles/github
- styles/github-dark
- styles/github-dark-dimmed
- styles/gml
- styles/googlecode
- styles/gradient-dark
- styles/gradient-light
- styles/grayscale
- styles/hybrid
- styles/idea
- styles/intellij-light
- styles/ir-black
- styles/isbl-editor-dark
- styles/isbl-editor-light
- styles/kimbie-dark
- styles/kimbie-light
- styles/lightfair
- styles/lioshi
- styles/magula
- styles/mono-blue
- styles/monokai
- styles/monokai-sublime
- styles/night-owl
- styles/nnfx-dark
- styles/nnfx-light
- styles/nord
- styles/obsidian
- styles/panda-syntax-dark
- styles/panda-syntax-light
- styles/paraiso-dark
- styles/paraiso-light
- styles/pojoaque
- styles/purebasic
- styles/qtcreator-dark
- styles/qtcreator-light
- styles/rainbow
- styles/routeros
- styles/school-book
- styles/shades-of-purple
- styles/srcery
- styles/stackoverflow-dark
- styles/stackoverflow-light
- styles/sunburst
- styles/tokyo-night-dark
- styles/tokyo-night-light
- styles/tomorrow-night-blue
- styles/tomorrow-night-bright
- styles/vs
- styles/vs2015
- styles/xcode
- styles/xt256