<div align="center">

# Iced Code Editor
A high-performance, canvas-based code editor widget for [Iced](https://github.com/iced-rs/iced).
[](https://crates.io/crates/iced-code-editor)
[](https://docs.rs/iced-code-editor)
[](https://github.com/LuDog71FR/iced-code-editor/blob/main/LICENSE)
[](https://crates.io/crates/iced-code-editor)
[](https://github.com/LuDog71FR/iced-code-editor/actions)
</div>
## Overview
This crate provides a fully-featured code editor widget with syntax highlighting, line numbers, text selection, and comprehensive keyboard navigation for the Iced GUI framework.
Screenshot of the demo application:

## Features
- **Syntax highlighting** for multiple programming languages via [syntect](https://github.com/trishume/syntect)
- **Line numbers** with styled gutter
- **Text selection** via mouse drag and keyboard shortcuts
- **Clipboard operations** (copy, paste)
- **Undo/Redo** with smart command grouping and configurable history
- **Custom scrollbars** with themed styling
- **Focus management** for multiple editors
- **Native Iced theme support** - Automatically adapts to all 23+ built-in Iced themes
- **Line wrapping** to split long lines
- **High performance** canvas-based rendering
- **Search and replace** text
## Planned features
- [ ] Multiple cursors for simultaneous editing at multiple positions
- [ ] Collapse/expand blocks
- [ ] Indentation-based or syntax-aware
- [ ] Minimap
- [ ] Auto-completion
## Quick Start
Add this to your `Cargo.toml`:
```toml
[dependencies]
iced = "0.14"
iced-code-editor = "0.3"
```
### Basic Example
Here's a minimal example to integrate the code editor into your Iced application:
```rust
use iced::widget::container;
use iced::{Element, Task};
use iced_code_editor::{CodeEditor, Message as EditorMessage};
struct MyApp {
editor: CodeEditor,
}
#[derive(Debug, Clone)]
enum Message {
EditorEvent(EditorMessage),
}
impl Default for MyApp {
fn default() -> Self {
let code = r#"fn main() {
println!("Hello, world!");
}
"#;
Self { editor: CodeEditor::new(code, "rust") }
}
}
impl MyApp {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::EditorEvent(event) => {
self.editor.update(&event).map(Message::EditorEvent)
}
}
}
fn view(&self) -> Element<'_, Message> {
container(self.editor.view().map(Message::EditorEvent))
.padding(20)
.into()
}
}
fn main() -> iced::Result {
iced::run(MyApp::update, MyApp::view)
}
```
## Keyboard Shortcuts
The editor supports a comprehensive set of keyboard shortcuts:
### Navigation
| **Arrow Keys** (Up, Down, Left, Right) | Move cursor |
| **Shift + Arrows** | Move cursor with selection |
| **Home** / **End** | Jump to start/end of line |
| **Shift + Home** / **Shift + End** | Select to start/end of line |
| **Ctrl + Home** / **Ctrl + End** | Jump to start/end of document |
| **Page Up** / **Page Down** | Scroll one page up/down |
### Editing
| **Backspace** | Delete character before cursor (or delete selection if text is selected) |
| **Delete** | Delete character after cursor (or delete selection if text is selected) |
| **Shift + Delete** | Delete selected text (same as Delete when selection exists) |
| **Enter** | Insert new line |
### Clipboard
| **Ctrl + C** or **Ctrl + Insert** | Copy selected text |
| **Ctrl + V** or **Shift + Insert** | Paste from clipboard |
### Undo/Redo
| **Ctrl + Z** | Undo last operation |
| **Ctrl + Y** | Redo last undone operation |
The editor features smart command grouping - consecutive typing is grouped into single undo operations, while navigation or deletion actions create separate undo points.
### Search and Replace
| **Ctrl + F** | Open search dialog |
| **Ctrl + H** | Open search and replace dialog |
## Usage Examples
### Changing Themes
The editor uses **TokyoNightStorm** as the default theme. It automatically adapts to any Iced theme. All 23+ built-in Iced themes are supported:
```rust
use iced_code_editor::theme;
// Apply any built-in Iced theme
editor.set_theme(theme::from_iced_theme(&iced::Theme::TokyoNightStorm));
editor.set_theme(theme::from_iced_theme(&iced::Theme::Dracula));
editor.set_theme(theme::from_iced_theme(&iced::Theme::Nord));
editor.set_theme(theme::from_iced_theme(&iced::Theme::CatppuccinMocha));
editor.set_theme(theme::from_iced_theme(&iced::Theme::GruvboxDark));
// Or use any theme from Theme::ALL
for theme in iced::Theme::ALL {
editor.set_theme(theme::from_iced_theme(theme));
}
```
### Getting and Setting Content
```rust
// Get current content
let content = editor.content();
// Check if content has been modified
if editor.is_modified() {
println!("Editor has unsaved changes");
}
// Mark content as saved (e.g., after saving to file)
editor.mark_saved();
```
### Enable/disable search/replace
The search/replace functionality is **enabled by default**. It can be toggled on or off. When disabled, search shortcuts (Ctrl+F, Ctrl+H, F3) are ignored and the search dialog is hidden:
```rust
// Disable search/replace functionality
editor.set_search_replace_enabled(false);
// Or use builder pattern during initialization
let editor = CodeEditor::new("code", "rs")
.with_search_replace_enabled(false);
// Check current state
if editor.search_replace_enabled() {
println!("Search and replace is available");
}
```
This is useful for read-only editors or when you want to provide your own search interface.
### Enable/disable line wrapping
Line wrapping is **enabled by default** at viewport width. Long lines can be wrapped automatically at the viewport width or at a fixed column:
```rust
// Enable line wrapping at viewport width
editor.set_wrap_enabled(true);
// Wrap at a fixed column (e.g., 80 characters)
let editor = CodeEditor::new("code", "rs")
.with_wrap_enabled(true)
.with_wrap_column(Some(80));
// Disable wrapping
editor.set_wrap_enabled(false);
// Check current state
if editor.wrap_enabled() {
println!("Line wrapping is active");
}
```
When enabled, wrapped lines show a continuation indicator (↪) in the line number gutter.
### Enable/disable line numbers
Line numbers are **displayed by default**. They can be hidden to maximize space for code:
```rust
// Hide line numbers
editor.set_line_numbers_enabled(false);
// Or use builder pattern during initialization
let editor = CodeEditor::new("code", "rs")
.with_line_numbers_enabled(false);
// Show line numbers (default behavior)
editor.set_line_numbers_enabled(true);
// Check current state
if editor.line_numbers_enabled() {
println!("Line numbers are visible");
}
```
When disabled, the gutter is completely removed (0px width), providing more horizontal space for code display.
### Changing font
The default font of the editor is `iced::Font::MONOSPACE`. It can be changed with one of the default `iced` font or by loading a specific font:
```rust
let font = iced::font::Family::SansSerif;
self.editor_left.set_font(font);
```
## Themes
The editor natively supports all built-in Iced themes with automatic color adaptation.
Each theme automatically provides:
- Optimized background and foreground colors
- Adaptive gutter (line numbers) styling
- Appropriate text selection colors
- Themed cursor appearance
- Custom scrollbar styling
- Subtle current line highlighting
The editor intelligently adapts colors from the Iced theme palette for optimal code readability.


## Supported Languages
The editor supports syntax highlighting for numerous languages via the `syntect` crate:
- **Rust** (`"rs"` or `"rust"`)
- **Python** (`"py"` or `"python"`)
- **JavaScript/TypeScript** (`"js"`, `"javascript"`, `"ts"`, `"typescript"`)
- **Lua** (`"lua"`)
- **C/C++** (`"c"`, `"cpp"`, `"c++"`)
- **Java** (`"java"`)
- **Go** (`"go"`)
- **HTML/CSS** (`"html"`, `"css"`)
- **Markdown** (`"md"`, `"markdown"`)
- And many more...
For a complete list, refer to the [syntect documentation](https://docs.rs/syntect/).
## Demo Application
A full-featured demo application is included in the `demo-app` directory, showcasing:
- File operations (open, save, save as)
- Theme switching
- Modified state tracking
- Clipboard operations
- Full keyboard navigation
Run it with:
```bash
cargo run --package demo-app --release
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Check [docs\DEV.md](https://github.com/LuDog71FR/iced-code-editor/blob/main/docs/DEV.md) for more details.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- Built with [Iced](https://github.com/iced-rs/iced) - A cross-platform GUI library for Rust
- Syntax highlighting powered by [syntect](https://github.com/trishume/syntect)