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 both dark and light themes:
68//!
69//! ```no_run
70//! use iced_code_editor::{CodeEditor, theme};
71//!
72//! // Create an editor with dark theme (default)
73//! let mut editor = CodeEditor::new("fn main() {}", "rs");
74//!
75//! // Switch to light theme
76//! editor.set_theme(theme::light(&iced::Theme::Light));
77//! ```
78//!
79//! # Keyboard Shortcuts
80//!
81//! The editor supports a comprehensive set of keyboard shortcuts:
82//!
83//! ## Navigation
84//!
85//! | Shortcut | Action |
86//! |----------|--------|
87//! | **Arrow Keys** (Up, Down, Left, Right) | Move cursor |
88//! | **Shift + Arrows** | Move cursor with selection |
89//! | **Home** / **End** | Jump to start/end of line |
90//! | **Shift + Home** / **Shift + End** | Select to start/end of line |
91//! | **Ctrl + Home** / **Ctrl + End** | Jump to start/end of document |
92//! | **Page Up** / **Page Down** | Scroll one page up/down |
93//!
94//! ## Editing
95//!
96//! | Shortcut | Action |
97//! |----------|--------|
98//! | **Backspace** | Delete character before cursor (or delete selection if text is selected) |
99//! | **Delete** | Delete character after cursor (or delete selection if text is selected) |
100//! | **Shift + Delete** | Delete selected text (same as Delete when selection exists) |
101//! | **Enter** | Insert new line |
102//!
103//! ## Clipboard
104//!
105//! | Shortcut | Action |
106//! |----------|--------|
107//! | **Ctrl + C** or **Ctrl + Insert** | Copy selected text |
108//! | **Ctrl + V** or **Shift + Insert** | Paste from clipboard |
109//!
110//! # Supported Languages
111//!
112//! The editor supports syntax highlighting through the `syntect` crate:
113//! - Python (`"py"` or `"python"`)
114//! - Lua (`"lua"`)
115//! - Rust (`"rs"` or `"rust"`)
116//! - JavaScript (`"js"` or `"javascript"`)
117//! - And many more...
118//!
119//! For a complete list, refer to the `syntect` crate documentation.
120//!
121//! # Command History Management
122//!
123//! The [`CommandHistory`] type provides fine-grained control over undo/redo operations.
124//! While the editor handles history automatically, you can access it directly for
125//! advanced use cases:
126//!
127//! ## Monitoring History State
128//!
129//! ```no_run
130//! use iced_code_editor::CommandHistory;
131//!
132//! let history = CommandHistory::new(100);
133//!
134//! // Check how many operations are available
135//! println!("Undo operations: {}", history.undo_count());
136//! println!("Redo operations: {}", history.redo_count());
137//!
138//! // Check if operations are possible
139//! if history.can_undo() {
140//!     println!("Can undo!");
141//! }
142//! ```
143//!
144//! ## Adjusting History Size
145//!
146//! You can dynamically adjust the maximum number of operations kept in history:
147//!
148//! ```no_run
149//! use iced_code_editor::CommandHistory;
150//!
151//! let history = CommandHistory::new(100);
152//!
153//! // Get current maximum
154//! assert_eq!(history.max_size(), 100);
155//!
156//! // Increase limit for memory-rich environments
157//! history.set_max_size(500);
158//!
159//! // Or decrease for constrained environments
160//! history.set_max_size(50);
161//! ```
162//!
163//! ## Clearing History
164//!
165//! You can reset the entire history when needed:
166//!
167//! ```no_run
168//! use iced_code_editor::CommandHistory;
169//!
170//! let history = CommandHistory::new(100);
171//!
172//! // Clear all undo/redo operations
173//! history.clear();
174//!
175//! assert_eq!(history.undo_count(), 0);
176//! assert_eq!(history.redo_count(), 0);
177//! ```
178//!
179//! ## Save Point Tracking
180//!
181//! Track whether the document has been modified since the last save:
182//!
183//! ```no_run
184//! use iced_code_editor::CommandHistory;
185//!
186//! let history = CommandHistory::new(100);
187//!
188//! // After loading or saving a file
189//! history.mark_saved();
190//!
191//! // Check if there are unsaved changes
192//! if history.is_modified() {
193//!     println!("Document has unsaved changes!");
194//! }
195//! ```
196
197mod canvas_editor;
198mod text_buffer;
199
200pub mod theme;
201
202pub use canvas_editor::{ArrowDirection, CodeEditor, CommandHistory, Message};
203pub use theme::{Catalog, Style, StyleFn, dark, light};