An open API service indexing awesome lists of open source software.

https://github.com/heckmon/code_forge

A powerful, feature-rich code editor widget created using Flutter
https://github.com/heckmon/code_forge

code-field code-forge flutter-code-editor flutter-code-forge flutter-code-snippet flutter-syntax-highlighter

Last synced: 8 days ago
JSON representation

A powerful, feature-rich code editor widget created using Flutter

Awesome Lists containing this project

README

          

βš’οΈ CodeForge


A powerful, feature-rich code editor created using Flutter


Bring VS Code-level editing experience to your Flutter apps


A complete and better alternative for re_editor, flutter_code_crafter, flutter_code_editor, code_text_field, etc



Pub Version


License


GitHub Stars


Platform

---


CodeForge Demo
large code support (tested with 100k+ lines) and LSP based intelligent lazy highlighting

> [!NOTE]
>
> CodeForge does **not** support Flutter web, as it relies on `dart:io` for core functionality. Web support may be considered in the future if dependencies allow.

### What's new in 5.2.0
- Greatly enhanced large text handling.

## ✨ Why CodeForge?

**CodeForge** is a next-generation code editor widget designed for developers who demand more. Whether you're building an IDE, a code snippet viewer, or an educational coding platform, CodeForge delivers:

| Feature | CodeForge | Others |
|---------|:---------:|:------:|
| 🎨 Syntax Highlighting | βœ… 180+ languages
[Availabe languages](https://github.com/reqable/re-highlight/tree/main/lib/languages) | βœ… |
| πŸ“ Code Folding | βœ… Smart detection | ⚠️ Limited |
| πŸ”Œ LSP Integration | βœ… Full support | ❌ |
| πŸ€– AI Completion | βœ… Multi-model | ❌ |
| ⚑ Semantic Tokens | βœ… Real-time | ❌ |
| 🎯 Diagnostics | βœ… Inline errors | ❌ |
| ↩️ Undo/Redo | βœ… Smart grouping | ⚠️ Basic |
| 🎨 Full Theming | βœ… Everything
[Available themes](https://github.com/reqable/re-highlight/tree/main/lib/styles) | ⚠️ Limited |

### What makes CodeForge different from other editors:
- Uses the rope data structure instead of regular char array to to handle large text.
- Uses flutter's low level `RenderBox` and `ParagrahBuilder` to render text insted of `TextField` for efficiency.
- Built in [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) client
- AI Code completion.

---

## 🎬 Features



πŸ€– AI Code Completion


Intelligent code suggestions powered by AI models like Gemini. Auto, manual, or mixed completion modes with smart debouncing.



AI Completion


πŸ”Œ LSP Integration


Full Language Server Protocol support with real-time diagnostics, hover documentation, Code Actions and semantic highlighting.



LSP Integration


πŸ“ Smart Code Folding


Collapse and expand code blocks with visual indicators. Navigate large files with ease.



Code Folding


🎨 Syntax Highlighting


Beautiful syntax highlighting for 180+ languages with customizable themes and semantic token support.



Syntax Highlighting




πŸ” Search and replace


Search and replace words like in VSCode.



Syntax Highlighting


### 🌟 More Features

πŸ“‹ Complete Feature List

#### Editor Core
- ⚑ **Rope Data Structure** β€” Optimized for large files
- 🎨 **180+ Languages** β€” Via `re_highlight` package
- πŸ“ **Code Folding** β€” Smart block detection
- πŸ“ **Indentation Guides** β€” Visual code structure
- πŸ”’ **Line Numbers** β€” With active line highlighting
- ↩️ **Smart Undo/Redo** β€” Timestamp-based grouping
- πŸ” **Search Highlighting** β€” Find and highlight matches
- βœ‚οΈ **Line Operations** β€” Move, duplicate, delete lines

#### LSP Features
- πŸ’‘ **Intelligent Completions** β€” Context-aware suggestions
- πŸ“– **Hover Documentation** β€” Rich markdown tooltips
- 🚨 **Real-time Diagnostics** β€” Errors and warnings
- 🎨 **Semantic Highlighting** β€” Token-based coloring
- πŸ“‘ **Multiple Protocols** β€” Stdio and WebSocket support

#### AI Features
- πŸ€– **Multi-Model Support** β€” Gemini and extensible
- βš™οΈ **Completion Modes** β€” Auto, manual, or mixed
- πŸ’Ύ **Response Caching** β€” Improved performance
- 🧹 **Smart Parsing** β€” Clean code extraction

#### Customization
- 🎨 **Full Theming** β€” Every element customizable
- πŸ“ **Gutter Styling** β€” Colors, icons, sizes
- ✨ **Selection Styling** β€” Cursor, selection, bubbles
- πŸ’¬ **Popup Styling** β€” Suggestions, hover details

---

## πŸ“¦ Installation

Add CodeForge to your `pubspec.yaml`:

```yaml
dependencies:
code_forge: ^5.2.0
```

Then run:

```bash
flutter pub get
```

---

## πŸš€ Quick Start

### Basic Usage

Import a theme and a language from the [re_highlight](https://pub.dev/packages/re_highlight) package and you are good to go. (Defaults to `langDart` and `vs2015Theme`):

```dart
import 'package:flutter/material.dart';
import 'package:code_forge/code_forge.dart';
import 'package:re_highlight/languages/python.dart';
import 'package:re_highlight/styles/atom-one-dark.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CodeForge(
language: langPython, // Defaults to langDart
editorTheme: atomOneDarkTheme, // Defaults to vs2015Theme
),
),
);
}
}
```

### With Controller

For more control over the editor:

```dart
class _EditorState extends State {
final _controller = CodeForgeController();
final _undoController = UndoRedoController();

@override
Widget build(BuildContext context) {
return CodeForge(
controller: _controller, // Optional controller for more features.
undoController: _undoController, // Optional undo controller to control the undo-redo operations.
);
}
}
```

---

πŸ”Œ LSP Integration

Connect to any Language Server Protocol compatible server for intelligent code assistance.

CodeForge provides a built-in LSP client that allows you to connect to any LSP server for intelligent highlighting, completions, hover details, diagnostics, and more.

## Types
#### There are two ways to configure LSP client with the `CodeForge`:
1. Using WebSocket (easy and recommended)
2. Using stdio

1. Using WebSocket

The class `LspSocketConfig` is used to connect to an LSP server using WebSocket. It takes the following parameters:
- `serverUrl`: The WebSocket URL of the LSP server.
- `filePath`: A filePath is required by the LSP server to provide completions and diagnostics.
- `workspacePath`: The workspace path is the current directory or the parent directory which holds the `filePath` file.
- `languageId`: This is a server specific parameter. eg: `'python'` is the language ID used in basedpyright/pyright language server.

You can easily start any language server using websocket using the [lsp-ws-proxy](https://github.com/qualified/lsp-ws-proxy) package. For example, to start the basedpyright language server, you can use the following command:

(On Android, you can use [Termux](https://github.com/termux/termux-app))

```bash
cd /Downloads/lsp-ws-proxy_linux # Navigate to the directory where lsp-ws-proxy is located

./lsp-ws-proxy --listen 5656 -- basedpyright-langserver --stdio # Start the pyright language server on port 5656
```

#### Example:
create a `LspSocketConfig` object and pass it to the `CodeForgeController` widget.

```dart
final lspConfig = LspSocketConfig(
workspacePath: "/home/athul/Projects/lsp",
languageId: "python",
serverUrl: "ws://localhost:5656"
),
```
Then pass the `lspConfig` instance to the `CodeForgeController` widget:

```dart
final _controller = CodeForgeController(
lspConfig: lspConfig // Pass the LspConfig here.
)

CodeForge(
controller: _controller, // Pass the controller here.
theme: anOldHopeTheme,
filePath: "/home/athul/Projects/lsp/example.py"
),
```

2. Using Stdio

This method is easy to startβ€”no terminal setup or extra packages are neededβ€”but it does require a bit more setup in your code. The `LspStdioConfig.start()` method connects to an LSP server using stdio and is asynchronous, so you'll typically use a `FutureBuilder` to handle initialization. It accepts the following parameters:
- `executable`: Location of the LSP server executable file.
- `args`: Arguments to pass to the LSP server executable.
- `filePath`: A filePath is required by the LSP server to provide completions and diagnostics.
- `workspacePath`: The workspace path is the current directory or parent directory which holds the `filePath` file.
- `languageId`: This is a server specific parameter. eg: `'python'` is the language ID used in pyright language server.

To get the `executable` path, you can use the `which` command in the terminal. For example, to get the path of the `basedpyright-langserver`, you can use the following command:

```bash
which basedpyright-langserver
```

#### Example:
Create an async method to initialize the LSP configuration.
```dart
Future _initLsp() async {
try {
final config = await LspStdioConfig.start(
executable: '/home/athul/.nvm/versions/node/v20.19.2/bin/basedpyright-langserver',
args: ['--stdio'],
workspacePath: '/home/athul/Projects/lsp',
languageId: 'python',
);

return config;
} catch (e) {
debugPrint('LSP Initialization failed: $e');
return null;
}
}
```
Then use a `FutureBuilder` to initialize the LSP configuration and pass it to the `CodeForgeController` widget:
```dart
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: FutureBuilder(
future: _initLsp(), // Call the async method to get the LSP config.
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return CodeForge(
editorTheme: anOldHopeTheme,
controller: CodeForgeController(
lspConfig: snapshot.data // Pass the config here.
),
filePath: '/home/athul/Projects/lsp/example.py',
textStyle: TextStyle(fontSize: 15, fontFamily: 'monospace'),
);
}
),
)
),
);
}
```


### Dart LSP Example Using Stdio

```dart
Future setupDartLsp() async {
return await LspStdioConfig.start(
executable: 'dart',
args: ['language-server', '--protocol=lsp'],
workspacePath: '/path/to/your/project',
languageId: 'dart',
);
}

// In your widget
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: FutureBuilder(
future: setupDartLsp(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
return CodeForge(
language: langDart,
textStyle: GoogleFonts.jetBrainsMono(),
controller: CodeForgeController(
lspConfig: snapshot.data
),
filePath: '/path/to/your/file.dart', // Mandatory field
)
},
),
),
),
);
}
```

---

🎨 Customization

CodeForge offers extensive customization options for every aspect of the editor.

### Theme & Styling

```dart
CodeForge(
controller: controller,
language: langDart,

// Editor theme (syntax colors)
editorTheme: vs2015Theme,

// Text styling
textStyle: GoogleFonts.jetBrainsMono(fontSize: 14),

// AI Completion styling
aiCompletionTextStyle: TextStyle(
color: Colors.grey, // Change the color of the AI completion text
fontStyle: FontStyle.italic, // Make the AI completion text italic
),

// Selection & cursor
selectionStyle: CodeSelectionStyle(
cursorColor: Colors.white,
selectionColor: Colors.blue.withOpacity(0.3),
cursorBubbleColor: Colors.blue,
),

// Gutter (line numbers & fold icons)
gutterStyle: GutterStyle(
lineNumberStyle: TextStyle(color: Colors.grey),
backgroundColor: Color(0xFF1E1E1E),
activeLineNumberColor: Colors.white,
foldedIconColor: Colors.grey,
unfoldedIconColor: Colors.grey,
errorLineNumberColor: Colors.red,
warningLineNumberColor: Colors.orange,
),

// Suggestion popup
suggestionStyle: SuggestionStyle(
backgroundColor: Color(0xFF252526),
textStyle: TextStyle(color: Colors.white),
elevation: 8,
),

// Hover documentation
hoverDetailsStyle: HoverDetailsStyle(
backgroundColor: Color(0xFF252526),
textStyle: TextStyle(color: Colors.white),
),

// Highlight matching text using [controller.findWord()] and [controller.findRegex()]
matchHighlightStyle: const MatchHighlightStyle(
currentMatchStyle: TextStyle(
backgroundColor: Color(0xFFFFA726),
),
otherMatchStyle: TextStyle(
backgroundColor: Color(0x55FFFF00),
),
),
)
```

### Feature Toggles

```dart
CodeForge(
// Enable/disable features
enableFolding: true, // Code folding
enableGutter: true, // Line numbers
enableGuideLines: true, // Indentation guides
enableGutterDivider: false, // Gutter separator line
enableSuggestions: true, // Autocomplete

// Behavior
readOnly: false, // Read-only mode
autoFocus: true, // Auto-focus on mount
lineWrap: false, // Line wrapping
)
```

---

πŸ“š API Reference

### CodeForge Widget

| Property | Type | Description |
|----------|------|-------------|
| `controller` | `CodeForgeController?` | Text and selection controller |
| `undoController` | `UndoRedoController?` | Undo/redo history controller |
| `language` | `Mode?` | Syntax highlighting language |
| `editorTheme` | `Map?` | Syntax color theme |
| `textStyle` | `TextStyle?` | Base text style |
| `lspConfig` | `LspConfig?` | LSP server configuration |
| `aiCompletion` | `AiCompletion?` | AI completion settings |
| `filePath` | `String?` | File path for LSP |
| `initialText` | `String?` | Initial editor content |
| `readOnly` | `bool` | Read-only mode |
| `enableFolding` | `bool` | Enable code folding |
| `enableGutter` | `bool` | Show line numbers |
| `enableGuideLines` | `bool` | Show indentation guides |
| `selectionStyle` | `CodeSelectionStyle?` | Selection styling |
| `gutterStyle` | `GutterStyle?` | Gutter styling |
| `suggestionStyle` | `SuggestionStyle?` | Suggestion popup styling |
| `hoverDetailsStyle` | `HoverDetailsStyle?` | Hover popup styling |
| `matchHighlightStyle` | `MatchHighlightStyle?` | Highlight the matching words
in the controller.findWord() API |

### CodeForgeController

```dart
final controller = CodeForgeController();

// Text operations
controller.text = 'Hello, World!';
String content = controller.text;

// Selection
controller.selection = TextSelection(baseOffset: 0, extentOffset: 5);

// Line operations
int lineCount = controller.lineCount;
String line = controller.getLineText(0);
int lineStart = controller.getLineStartOffset(0);

// Folding
controller.foldAll();
controller.unfoldAll();
controller.toggleFold(lineNumber);

// Search
controller.searchHighlights = [
SearchHighlight(start: 0, end: 5, color: Colors.yellow),
];

// Scoll to a line
controller.scollToLine(int line);

// Editor decorations
controller.setGitDiffDecorations(
addedRanges: [(int startLine, int endLine), (int startline, int endLine), ... etc],
removedRanges: [same pattern as above],
modifiedRanges: [same pattern as above],
addedColor: const Color(0xFF4CAF50),
removedColor: const Color(0xFFE53935),
modifiedColor: const Color(0xFF2196F3),
)
```

### GutterStyle

```dart
GutterStyle({
TextStyle? lineNumberStyle,
Color? backgroundColor,
double? gutterWidth,
IconData foldedIcon,
IconData unfoldedIcon,
double? foldingIconSize,
Color? foldedIconColor,
Color? unfoldedIconColor,
Color? activeLineNumberColor,
Color? inactiveLineNumberColor,
Color errorLineNumberColor,
Color warningLineNumberColor,
Color? foldedLineHighlightColor,
})
```

### CodeSelectionStyle

```dart
CodeSelectionStyle({
Color? cursorColor,
Color selectionColor,
Color cursorBubbleColor,
})
```

### SuggestionStyle
```dart
SuggestionStyle(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
backgroundColor: Colors.grey[900]!,
focusColor: Colors.blue.withOpacity(0.3),
hoverColor: Colors.blue.withOpacity(0.1),
splashColor: Colors.blue.withOpacity(0.2),
textStyle: TextStyle(color: Colors.white),
)
```

### HoverDetailsStyle
```dart
HoverDetailsStyle(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
backgroundColor: Colors.grey[850]!,
focusColor: Colors.blue.withOpacity(0.3),
hoverColor: Colors.blue.withOpacity(0.1),
splashColor: Colors.blue.withOpacity(0.2),
textStyle: TextStyle(color: Colors.white),
)
```

### MatchHighlightStyle
```dart
matchHighlightStyle: const MatchHighlightStyle(
currentMatchStyle: TextStyle(
backgroundColor: Color(0xFFFFA726),
),
otherMatchStyle: TextStyle(
backgroundColor: Color(0x55FFFF00),
),
),
```

---

⌨️ Keyboard Shortcuts


CodeForge supports a variety of keyboard shortcuts for efficient editing:

### Editing
- **Ctrl+C** β€” Copy selected text.
- **Ctrl+X** β€” Cut selected text.
- **Ctrl+V** β€” Paste text.
- **Ctrl+A** β€” Select all text.
- **Ctrl+D** β€” Duplicate current line.
- **Ctrl+Z** β€” Undo last action.
- **Ctrl+Y** β€” Redo last action.
- **Ctrl+Backspace** β€” Delete word backward.
- **Ctrl+Delete** β€” Delete word forward.

### Navigation
- **Ctrl+Arrow Left** β€” Move cursor to previous word.
- **Ctrl+Arrow Right** β€” Move cursor to next word.
- **Ctrl+Shift+Arrow Left** β€” Select to previous word.
- **Ctrl+Shift+Arrow Right** β€” Select to next word.
- **Ctrl+Shift+Arrow Up** β€” Move current line up.
- **Ctrl+Shift+Arrow Down** β€” Move current line down.

### Indentation
- **Tab** β€” Indent current line or accept AI completion/suggestion.
- **Shift+Tab** β€” Unindent current line.

### Suggestions & AI Completion
- **Ctrl+.** β€” Show available LSP code actions.
- **Ctrl + Shift + Space** β€” Show available LSP signature help.
- **Arrow Up/Down** β€” Navigate through suggestions.
- **Enter/Tab** β€” Accept current suggestion.
- **Escape** β€” Close suggestions or hover details.

### Selection
- **Shift+Arrow Keys** β€” Extend selection.
- **Shift+Home** β€” Select to line start.
- **Shift+End** β€” Select to line end.

## Search
- **Ctrl + F** β€” Show search bar.
- **Ctrl + H** β€” Show replace bar.

---

## 🀝 Contributing

Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## πŸ“„ License

This project is licensed under the MIT License - see the [LICENSE](https://github.com/heckmon/code_forge/blob/main/LICENSE) file for details.

---

## πŸ™ Acknowledgments

- [re_highlight](https://pub.dev/packages/re_highlight) β€” Syntax highlighting
- [markdown_widget](https://pub.dev/packages/markdown_widget) β€” Markdown rendering
- [web_socket_channel](https://pub.dev/packages/web_socket_channel) β€” WebSocket support

---


Built with ❀️ for the Flutter community



Star on GitHub