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