A customizable code text field supporting syntax highlighting

Overview

CodeField

A customizable code text field supporting syntax highlighting

Pub Website shields.io GitHub license Awesome Flutter

Live demo

A live demo showcasing a few language / themes combinaisons

Showcase

The experimental VM dlox uses CodeField in its online editor

Features

  • Code highlight for 189 built-in languages with 90 themes thanks to flutter_highlight
  • Easy language highlight customization through the use of theme maps
  • Fully customizable code field style through a TextField like API
  • Handles horizontal/vertical scrolling and vertical expansion
  • Supports code modifiers
  • Works on Android, iOS, and Web

Code modifiers help manage indents automatically

The editor is wrapped in a horizontal scrollable container to handle long lines

Installing

In the pubspec.yaml of your flutter project, add the following dependency:

dependencies:
  ...
  code_text_field: 

latest version

In your library add the following import:

import 'package:code_text_field/code_field.dart';

Simple example

A CodeField widget works with a CodeController which dynamically parses the text input according to a language and renders it with a theme map

import 'package:flutter/material.dart';
import 'package:code_text_field/code_field.dart';
// Import the language & theme
import 'package:highlight/languages/dart.dart';
import 'package:flutter_highlight/themes/monokai-sublime.dart';

class CodeEditor extends StatefulWidget {
  @override
  _CodeEditorState createState() => _CodeEditorState();
}

class _CodeEditorState extends State<CodeEditor> {
  CodeController? _codeController;

  @override
  void initState() {
    super.initState();
    final source = "void main() {\n    print(\"Hello, world!\");\n}";
    // Instantiate the CodeController
    _codeController = CodeController(
      text: source,
      language: dart,
      theme: monokaiSublimeTheme,
    );
  }

  @override
  void dispose() {
    _codeController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CodeField(
      controller: _codeController!,
      textStyle: TextStyle(fontFamily: 'SourceCode'),
    );
  }
}

Here, the monospace font Source Code Pro has been added to the assets folder and to the pubspec.yaml file

Parser options

On top of a language definition, world-wise styling can be specified in the stringMap field

_codeController = CodeController(
  //...
  stringMap: {
    "Hello": TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
    "world": TextStyle(fontStyle: FontStyle.italic, color: Colors.green),
  },
);

More complex regexes may also be used with the patternMap. When a language is used though, its regexes patterns take precedence over patternMap and stringMap.

_codeController = CodeController(
  //...
  patternMap: {
    r"\B#[a-zA-Z0-9]+\b":
        TextStyle(fontWeight: FontWeight.bold, color: Colors.purpleAccent),
  },
);

Both patternMap and stringMap can be used without specifying a language

_codeController = CodeController(
  text: source,
  patternMap: {
    r'".*"': TextStyle(color: Colors.yellow),
    r'[a-zA-Z0-9]+\(.*\)': TextStyle(color: Colors.green),
  },
  stringMap: {
    "void": TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
    "print": TextStyle(fontWeight: FontWeight.bold, color: Colors.blue),
  },
);

Code Modifiers

Code modifiers can be created to react to special keystrokes. The default modifiers handle tab to space & automatic indentation. Here's the implementation of the default TabModifier

class TabModifier extends CodeModifier {
  const TabModifier() : super('\t');

  @override
  TextEditingValue? updateString(
      String text, TextSelection sel, EditorParams params) {
    final tmp = replace(text, sel.start, sel.end, " " * params.tabSpaces);
    return tmp;
  }
}

API

CodeField

CodeField({
Key? key,
  required this.controller,
  this.minLines,
  this.maxLines,
  this.expands = false,
  this.background,
  this.decoration,
  this.textStyle,
  this.padding = const EdgeInsets.symmetric(),
  this.lineNumberStyle = const LineNumberStyle(),
  this.cursorColor,
  this.textSelectionTheme,
  this.lineNumberBuilder,
})
LineNumberStyle({
  this.width = 42.0,
  this.textAlign = TextAlign.right,
  this.margin = 10.0,
  this.textStyle,
  this.background,
})

CodeController

CodeController({
  String? text,
  this.language,
  this.theme,
  this.patternMap,
  this.stringMap,
  this.params = const EditorParams(),
  this.modifiers = const <CodeModifier>[
    const IntendModifier(),
    const CloseBlockModifier(),
    const TabModifier(),
  ],
})

Limitations

  • Autocomplete disabling on android doesn't work yet
  • The TextField cursor doesn't seem to be handling space inputs properly on the web platform. Pending issue resolution. The flag webSpaceFix fixes it by swapping spaces with transparent middle points.

Notes

A breaking change to the TextEditingController was introduced in flutter beta, dev & master channels. The branch beta should comply with those changes.

Comments
  • Publish new version to include lineNumbers functionality

    Publish new version to include lineNumbers functionality

    First off, great library! Thanks for writing & maintaining it!

    I'd like to use the lineNumbers visibility toggle you added into CodeField but I noticed the package published on pub.dev is a little outdated (most recent version was published around a year ago).

    Would you be able to publish a new version with the most recent changes?

    opened by thekiwi 8
  • Enable Selection for disabled Textfield

    Enable Selection for disabled Textfield

    Hi,

    I am using the CodeField mainly for displaying code, rather then writing it. So mainly I have it "enabled = false". Nonetheless I'd like to select some code snippets here and there, but as I see, the selection is only possible on enabled/writeable Textfields.

    Is this possible?

    Thanks in advance, Mark

    opened by S-Man42 7
  • Dotted spaces on macos

    Dotted spaces on macos

    Using:

    code_text_field: ^1.0.1-2

    Having the following source code:

    return new CodeField(
          controller: this._controller,
          textStyle: TextStyle(fontFamily: 'SourceCode'),
          lineNumberStyle: LineNumberStyle(),
          expands: true,
        );
    

    It looks good in browser: Снимок экрана 2021-08-25 в 18 32 15

    but on macos the spaces are dotted: Снимок экрана 2021-08-25 в 18 33 36

    Is it code_field issue? Any workaround? I'm happy to assist if necessary.

    opened by 4ntoine 7
  • TextField shrinks to one line on click

    TextField shrinks to one line on click

    There is a bug with current master.

    1. Run the example from this package in Chrome. The window shows as usual: image

    2. Click inside the text field. The field shrinks to one line: image

    This is not happening with v1.0.2.

    I nailed it down to this line: https://github.com/BertrandBev/code_field/blob/befb10f12db622400c86ca388edc67c91b550774/lib/src/code_field.dart#L278 Comment it out, and it works as before.

    The change was introduced in https://github.com/BertrandBev/code_field/pull/36/files @ihorkozar what was the motivation for it?

    opened by alexeyinkin 5
  • Added onChanged callback to CodeField

    Added onChanged callback to CodeField

    I think the onChanged callback should've been on CodeField and not CodeController. CodeController extends TextEditingController and it's possible to use addListener there. The issue for me is this callback fires on every text change, focus change etc. onChanged on CodeField fires only if the text changes, which may in many cases be more useful.

    opened by leoshusar 4
  • Desktop build

    Desktop build

    I could build the example for Linux target by removing the dependency to keyboard_visibility. It involved to remove the package dependency in pubspec.yaml, and to comment / remove lines 7, 115-116, 129-130 in code_field.dart.

    I don't know how much the keyboard_visibility is necessary on mobile platforms, but it would be great to find a way to have a fully cross platform package for this project.

    If this dependency is necessary, maybe we could find another way to achieve it without dependency, just by handwritten code (I think I already made something like that in an app).

    What do you think about that ?

    opened by johannphilippe 4
  • Bug: colors changed in web when cursor is set

    Bug: colors changed in web when cursor is set

    There is some bug in the live demo: i can scroll down and see the correctly highlighted area: Снимок экрана 2021-07-23 в 17 59 21

    However if i set the cursor the colors are changed: Снимок экрана 2021-07-23 в 17 59 28

    See "moveTo" color is changed.

    It happens not in all the themes. Let me know if you can reproduce it or i will provide more details on this.

    opened by 4ntoine 3
  • Updates to CodeField API - isDense, smartQuotesType, keyboardType

    Updates to CodeField API - isDense, smartQuotesType, keyboardType

    • Added isDense to the API as an optional parameter with null default value (same as out-of-the-box TextField).
    • Amended smartQuotesType to be an optional parameter with null default value (same as out-of-the-box TextField).
    • Amended keyboardType to be an optional parameter with null default value (same as out-of-the-box TextField). This was previously set to TextInputType.password, which was preventing users from clicking 'enter' to create new lines.
    • Created a MacOS Desktop example app to help with debugging
    opened by mack-at-pieces 2
  • Added condition on _onKey in code_field.dart to disable tab in readonly mode

    Added condition on _onKey in code_field.dart to disable tab in readonly mode

    Updated as of Apr 26th:

    • Includes API in CodeController to manually set the cursor position
    • Adds an onTap parameter to CodeEditor so user can pass onTap callback into TextField
    opened by mack-at-pieces 2
  • [Bug] Line numbers over 999 wrap

    [Bug] Line numbers over 999 wrap

    I opened demo https://bertrandbev.github.io/code_field and tried copy-paste code for test performance

    When i puted over 999 code lines i received bug with line numbers wrap

    image

    opened by SergeShkurko 2
  • Add more control methods to controller

    Add more control methods to controller

    Hello, I'm connecting the Code text field to a virtual keyboard (provided here : https://pub.dev/packages/new_virtual_keyboard/install) It works fine calling the insertStr of the controller to insert characters. But, if I receive a backspace from virtual keyboard, I would need to have a method to remove a character, or selection. Thanks for your work

    opened by johannphilippe 2
  • Invalid value: Only valid value is x: x

    Invalid value: Only valid value is x: x

    I am implementing undo/redo function. When I assign codeController An exception occurred while texting.

      final codeController =  currentNode.codeController;
    
      codeController.text = '1';
      codeController.text = '12';
      codeController.text = '123';
      codeController.text = '123';
      codeController.text = '12';
      codeController.text = '1';
    

    error message:

    ======== Exception caught by gesture ===============================================================
    The following RangeError was thrown while handling a gesture:
    RangeError (index): Invalid value: Only valid value is 0: -1
    
    When the exception was thrown, this was the stack: 
    #0      _StringBase.[] (dart:core-patch/string_patch.dart:258:41)
    #1      CodeController.value= (package:code_text_field/src/code_field/code_controller.dart:165:33)
    #2      TextEditingController.text= (package:flutter/src/widgets/editable_text.dart:159:5)
    #3      EditPage.build.<anonymous closure> (package:summer/view/edit/edit_view.dart:38:26)
    #4      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1077:21)
    #5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
    #6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
    #7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
    

    The above errors are reported only in CodeController and CodeField, but they are normal in TextEditingController and TextField. The above errors can easily be repeated, and the complete code will not be pasted.

    opened by CurrentIndex 0
  • README Update for theme and CodeTheme

    README Update for theme and CodeTheme

    Thanks for your open source contributions!

    The README still shows usage of the once-deprecated and now-deleted theme argument for CodeController, where now a wrapping CodeTheme with CodeThemeData are needed.

    Thanks for updating the executable examples, that made it straightforward to find a working usage.

    opened by semperos 0
  • Use onKeyEvent instead of onKey in FocusNode

    Use onKeyEvent instead of onKey in FocusNode

    Here we use onKey to set the listener on FocusNode: https://github.com/BertrandBev/code_field/blob/66d4e56f14bc0073cd967149a929c6b670ffc74c/lib/src/code_field/code_field.dart#L121

    The doc says it is a legacy property and will be deprecated in the future. The recommended alternative is onKeyEvent.

    opened by alexeyinkin 0
  • Shifting scroll highlight when scrolling beyond bounds of code editor

    Shifting scroll highlight when scrolling beyond bounds of code editor

    I'm currently using the CodeEditor for MacOS and experiencing an issue where the scroll highlight shakes and shifts when dragging past the bounds of the CodeEditor.

    I'm unsure where this issue lies, whether it be something wrong with my code or the editor itself, but perhaps @BertrandBev or @alexeyinkin you may be able to shed some light here.

    @alexeyinkin I noticed you do not experience this problem in your project here (https://play.beam.apache.org/), so perhaps there's something I can do to also resolve this.

    Video attached.

    https://user-images.githubusercontent.com/30325757/175952195-35a111e2-6b36-4703-9b61-8ff120359573.mov

    opened by mack-at-pieces 3
A powerful extended official text for Flutter, which supports Speical Text(Image,@somebody), Custom Background, Custom overFlow, Text Selection.

Extended official text to build special text like inline image or @somebody quickly,it also support custom background,custom over flow and custom selection toolbar and handles.

FlutterCandies 509 Jan 4, 2023
A Flutter package to parse text and make them into linkified text widget

?? Flutter Parsed text A Flutter package to parse text and extract parts using predefined types like url, phone and email and also supports Regex. Usa

Fayeed Pawaskar 213 Dec 27, 2022
Rich Text renderer that parses Contentful Rich Text JSON object and returns a renderable Flutter widget

Contentful Rich Text Renderer for Flutter Rich Text renderer that parses Contentful Rich Text field JSON output and produces a Flutter Widget tree tha

Kumanu 45 Nov 10, 2022
Text Editor in Flutter for Android and iOS to help free write WYSIWYG HTML code

Flutter Summernote Text Editor in Flutter for Android and iOS to help free write WYSIWYG HTML code based on Summernote 0.8.18 javascript wrapper. NOTI

Chandra Abdul Fattah 41 Sep 12, 2022
A masked text for Flutter.

flutter_masked_text Masked text input for flutter. Alert Hi guys! Unfortunately, I'm not developing mobile anymore. This repo will not receive updates

Ben-hur Santos Ott 264 Dec 21, 2022
Soft and gentle rich text editing for Flutter applications.

About Zefyr Soft and gentle rich text editing for Flutter applications. You are viewing early dev preview version of this package which is no longer a

Memspace 2.2k Jan 8, 2023
Flutter widget that automatically resizes text to fit perfectly within its bounds.

Flutter widget that automatically resizes text to fit perfectly within its bounds. Show some ❤️ and star the repo to support the project Resources: Do

Simon Leier 1.8k Jan 3, 2023
Soft and gentle rich text editing for Flutter applications

Soft and gentle rich text editing for Flutter applications. Zefyrka is a fork of Zefyr package with the following improvements: support Flutter 2.0 op

null 85 Dec 21, 2022
Arc Text Widget for Flutter

Flutter Arc Text Renders text along the arc. See demo. The story behind the plugin is here. Basic usage class MyApp extends StatelessWidget

Kirill Bubochkin 15 Oct 18, 2021
A Tricky Solution for Implementing Inline-Image-In-Text Feature in Flutter.

A Tricky Solution for Implementing Inline-Image-In-Text Feature in Flutter.

Bytedance Inc. 646 Dec 29, 2022
A low code editor with the full power of flutter.

flutter_blossom ?? Low code editor with the full power of flutter. Think in flutter, watch your ideas come to life, plan ahead and let your creativity

Flutter Blossom 0 Dec 2, 2021
A customised Flutter TextFormField to input international phone number along with country code.

International Phone Field Package A customised Flutter TextFormField to input international phone number along with country code. This widget can be u

Vansh Goel 118 Jan 5, 2023
Masked text field - A flutter package for masked text field for formet your text and good UI

Masked Text Field Masked Text Field Features A package for masked text field for

Alok Dubey 7 Sep 4, 2022
Syntax highlighting for Dart and Flutter

highlight.dart Syntax highlighting for Dart and Flutter, which supports lots of languages and themes. View gallery built with Flutter web Package Vers

GitTouch 181 Jan 8, 2023
A Flutter package that provides a dropdown form field using a dropdown button inside a form field.

Dropdown form field A dropdown form field using a dropdown button inside a form field. Demo Features Can be used as regular form field. Simple to impl

Carlos Eugenio Torres 72 Jan 1, 2023
Detectable text field - Flutter Text widgets with detection features

detectable_text_field Text widgets with detection features. You can detect hasht

null 0 Feb 2, 2022
A text field that displays text on different languages based on your selection.

translatable_text_field A text field that displays text on different languages based on your selection. Its basic idea is that you place this fields i

null 0 Mar 13, 2022
Dynamic Text Highlighting (DTH) package for Dart & Flutter.

Dynamic Text Highlighting (DTH) This package is used to highlight, in a completely dynamic way, keywords, or phrases, wherever they are present in a s

null 34 Oct 3, 2022
Dynamic Text Highlighting (DTH) package for Dart & Flutter.

Dynamic Text Highlighting (DTH) This package is used to highlight, in a completely dynamic way, keywords, or phrases, wherever they are present in a s

null 34 Oct 3, 2022
Simple Flutter text highlighting at the character-level.

substring_highlight Highlight Flutter text at the character-level. Designed for case-insensitive search-term highlighting, a single search term sub-st

Peter Alvin 39 Nov 16, 2022