iced_code_editor/lib.rs
1//! A high-performance code editor widget for Iced.
2//!
3//! This crate provides a canvas-based code editor with syntax highlighting,
4//! line numbers, and text selection capabilities for the Iced GUI framework.
5//!
6//! # Features
7//!
8//! - **Syntax highlighting** for multiple programming languages
9//! - **Line numbers** with styled gutter
10//! - **Text selection** via mouse drag and keyboard
11//! - **Clipboard operations** (copy, paste)
12//! - **Custom scrollbars** with themed styling
13//! - **Focus management** for multiple editors
14//! - **Dark & light themes** support with customizable colors
15//! - **Undo/Redo** with command history
16//!
17//! # Example
18//!
19//! ```no_run
20//! use iced::widget::container;
21//! use iced::{Element, Task};
22//! use iced_code_editor::{CodeEditor, Message as EditorMessage};
23//!
24//! struct MyApp {
25//! editor: CodeEditor,
26//! }
27//!
28//! #[derive(Debug, Clone)]
29//! enum Message {
30//! EditorEvent(EditorMessage),
31//! }
32//!
33//! impl Default for MyApp {
34//! fn default() -> Self {
35//! let code = r#"fn main() {
36//! println!("Hello, world!");
37//! }
38//! "#;
39//!
40//! Self { editor: CodeEditor::new(code, "rust") }
41//! }
42//! }
43//!
44//! impl MyApp {
45//! fn update(&mut self, message: Message) -> Task<Message> {
46//! match message {
47//! Message::EditorEvent(event) => {
48//! self.editor.update(&event).map(Message::EditorEvent)
49//! }
50//! }
51//! }
52//!
53//! fn view(&self) -> Element<'_, Message> {
54//! container(self.editor.view().map(Message::EditorEvent))
55//! .padding(20)
56//! .into()
57//! }
58//! }
59//!
60//! fn main() -> iced::Result {
61//! iced::run(MyApp::update, MyApp::view)
62//! }
63//! ```
64//!
65//! # Themes
66//!
67//! The editor supports all native Iced themes with automatic color adaptation:
68//!
69//! ```no_run
70//! use iced_code_editor::{CodeEditor, theme};
71//!
72//! // Create an editor (defaults to Tokyo Night Storm theme)
73//! let mut editor = CodeEditor::new("fn main() {}", "rs");
74//!
75//! // Switch to any Iced theme
76//! editor.set_theme(theme::from_iced_theme(&iced::Theme::Dracula));
77//! editor.set_theme(theme::from_iced_theme(&iced::Theme::CatppuccinMocha));
78//! editor.set_theme(theme::from_iced_theme(&iced::Theme::Nord));
79//! ```
80//!
81//! # Keyboard Shortcuts
82//!
83//! The editor supports a comprehensive set of keyboard shortcuts:
84//!
85//! ## Navigation
86//!
87//! | Shortcut | Action |
88//! |----------|--------|
89//! | **Arrow Keys** (Up, Down, Left, Right) | Move cursor |
90//! | **Shift + Arrows** | Move cursor with selection |
91//! | **Home** / **End** | Jump to start/end of line |
92//! | **Shift + Home** / **Shift + End** | Select to start/end of line |
93//! | **Ctrl + Home** / **Ctrl + End** | Jump to start/end of document |
94//! | **Page Up** / **Page Down** | Scroll one page up/down |
95//!
96//! ## Editing
97//!
98//! | Shortcut | Action |
99//! |----------|--------|
100//! | **Backspace** | Delete character before cursor (or delete selection if text is selected) |
101//! | **Delete** | Delete character after cursor (or delete selection if text is selected) |
102//! | **Shift + Delete** | Delete selected text (same as Delete when selection exists) |
103//! | **Enter** | Insert new line |
104//!
105//! ## Clipboard
106//!
107//! | Shortcut | Action |
108//! |----------|--------|
109//! | **Ctrl + C** or **Ctrl + Insert** | Copy selected text |
110//! | **Ctrl + V** or **Shift + Insert** | Paste from clipboard |
111//!
112//! # Supported Languages
113//!
114//! The editor supports syntax highlighting through the `syntect` crate:
115//! - Python (`"py"` or `"python"`)
116//! - Lua (`"lua"`)
117//! - Rust (`"rs"` or `"rust"`)
118//! - JavaScript (`"js"` or `"javascript"`)
119//! - And many more...
120//!
121//! For a complete list, refer to the `syntect` crate documentation.
122//!
123//! # Command History Management
124//!
125//! The [`CommandHistory`] type provides fine-grained control over undo/redo operations.
126//! While the editor handles history automatically, you can access it directly for
127//! advanced use cases:
128//!
129//! ## Monitoring History State
130//!
131//! ```no_run
132//! use iced_code_editor::CommandHistory;
133//!
134//! let history = CommandHistory::new(100);
135//!
136//! // Check how many operations are available
137//! println!("Undo operations: {}", history.undo_count());
138//! println!("Redo operations: {}", history.redo_count());
139//!
140//! // Check if operations are possible
141//! if history.can_undo() {
142//! println!("Can undo!");
143//! }
144//! ```
145//!
146//! ## Adjusting History Size
147//!
148//! You can dynamically adjust the maximum number of operations kept in history:
149//!
150//! ```no_run
151//! use iced_code_editor::CommandHistory;
152//!
153//! let history = CommandHistory::new(100);
154//!
155//! // Get current maximum
156//! assert_eq!(history.max_size(), 100);
157//!
158//! // Increase limit for memory-rich environments
159//! history.set_max_size(500);
160//!
161//! // Or decrease for constrained environments
162//! history.set_max_size(50);
163//! ```
164//!
165//! ## Clearing History
166//!
167//! You can reset the entire history when needed:
168//!
169//! ```no_run
170//! use iced_code_editor::CommandHistory;
171//!
172//! let history = CommandHistory::new(100);
173//!
174//! // Clear all undo/redo operations
175//! history.clear();
176//!
177//! assert_eq!(history.undo_count(), 0);
178//! assert_eq!(history.redo_count(), 0);
179//! ```
180//!
181//! ## Save Point Tracking
182//!
183//! Track whether the document has been modified since the last save:
184//!
185//! ```no_run
186//! use iced_code_editor::CommandHistory;
187//!
188//! let history = CommandHistory::new(100);
189//!
190//! // After loading or saving a file
191//! history.mark_saved();
192//!
193//! // Check if there are unsaved changes
194//! if history.is_modified() {
195//! println!("Document has unsaved changes!");
196//! }
197//! ```
198
199// Initialize rust-i18n for the entire crate
200rust_i18n::i18n!("locales", fallback = "en");
201
202mod canvas_editor;
203mod text_buffer;
204
205pub mod i18n;
206pub mod theme;
207
208pub use canvas_editor::{ArrowDirection, CodeEditor, CommandHistory, Message};
209pub use i18n::{Language, Translations};
210pub use theme::{Catalog, Style, StyleFn, from_iced_theme};