9.6 KiB
Terminal.rs Reorganization Plan
This document identifies sections of src/terminal.rs (2336 lines) that could be extracted into separate files to improve code organization, maintainability, and testability.
Summary of Proposed Extractions
| New File | Lines | Primary Contents |
|---|---|---|
src/cell.rs |
~90 | Cell, Color, CursorShape |
src/color.rs |
~115 | ColorPalette and color parsing |
src/mouse.rs |
~110 | MouseTrackingMode, MouseEncoding, encode_mouse() |
src/scrollback.rs |
~100 | ScrollbackBuffer ring buffer |
src/terminal_commands.rs |
~30 | TerminalCommand, Direction |
src/stats.rs |
~45 | ProcessingStats |
Total extractable: ~490 lines (reducing terminal.rs by ~21%)
1. Cell Types and Color Enum
Lines: 30-87 (Cell, Color, CursorShape)
Contents:
Cellstruct (lines 31-45) - terminal grid cell with character and attributesimpl Default for Cell(lines 47-60)Colorenum (lines 63-69) -Default,Rgb(u8, u8, u8),Indexed(u8)CursorShapeenum (lines 72-87) - cursor style variants
Proposed file: src/cell.rs
Dependencies:
// No external dependencies - these are self-contained types
Exports needed by terminal.rs:
pub use cell::{Cell, Color, CursorShape};
Challenges:
- None. These are simple data types with no logic dependencies.
Benefits:
CellandColorare referenced by renderer and could be imported directly- Makes the core data structures discoverable
- Easy to test color conversion independently
2. Color Palette
Lines: 119-240
Contents:
ColorPalettestruct (lines 120-128) - 256-color palette storageimpl Default for ColorPalette(lines 130-177) - ANSI + 216 color cube + grayscaleColorPalette::parse_color_spec()(lines 181-209) - parse#RRGGBBandrgb:RR/GG/BBColorPalette::to_rgba()(lines 212-224) - foreground color conversionColorPalette::to_rgba_bg()(lines 227-239) - background color conversion
Proposed file: src/color.rs
Dependencies:
use crate::cell::Color; // For Color enum
Challenges:
- Depends on
Colorenum (extract cell.rs first) to_rgba()andto_rgba_bg()are called by the renderer
Benefits:
- Color parsing logic is self-contained and testable
- Palette initialization is complex (color cube math) and benefits from isolation
- Could add color scheme loading from config files in the future
3. Mouse Tracking and Encoding
Lines: 89-117, 962-1059
Contents:
MouseTrackingModeenum (lines 90-103)MouseEncodingenum (lines 106-117)Terminal::encode_mouse()method (lines 964-1059) - encode mouse events for PTY
Proposed file: src/mouse.rs
Dependencies:
// MouseTrackingMode and MouseEncoding are self-contained enums
// encode_mouse() would need to be a standalone function or trait
Refactoring approach:
// In mouse.rs
pub fn encode_mouse_event(
tracking: MouseTrackingMode,
encoding: MouseEncoding,
button: u8,
col: u16,
row: u16,
pressed: bool,
is_motion: bool,
modifiers: u8,
) -> Vec<u8>
Challenges:
encode_mouse()is currently a method onTerminalbut only readsmouse_trackingandmouse_encoding- Need to change call sites to pass mode/encoding explicitly, OR keep as Terminal method but move enums
Benefits:
- Mouse protocol logic is self-contained and well-documented
- Could add unit tests for X10, SGR, URXVT encoding without instantiating Terminal
4. Scrollback Buffer
Lines: 314-425
Contents:
ScrollbackBufferstruct (lines 326-335) - Kitty-style ring bufferScrollbackBuffer::new()(lines 340-351) - lazy allocationScrollbackBuffer::len(),is_empty(),is_full()(lines 354-369)ScrollbackBuffer::push()(lines 377-403) - O(1) ring buffer insertionScrollbackBuffer::get()(lines 407-415) - logical index accessScrollbackBuffer::clear()(lines 419-424)
Proposed file: src/scrollback.rs
Dependencies:
use crate::cell::Cell; // For Vec<Cell> line storage
Challenges:
- Depends on
Celltype (extract cell.rs first) - Otherwise completely self-contained with great documentation
Benefits:
- Ring buffer is a reusable data structure
- Excellent candidate for unit testing (push, wrap-around, get by index)
- Performance-critical code that benefits from isolation for profiling
5. Terminal Commands
Lines: 8-28
Contents:
TerminalCommandenum (lines 10-19) - commands sent from terminal to applicationDirectionenum (lines 22-28) - navigation direction
Proposed file: src/terminal_commands.rs
Dependencies:
// No dependencies - self-contained enums
Challenges:
- Very small extraction, but cleanly separates protocol from implementation
Benefits:
- Defines the terminal-to-application interface
- Could grow as more custom OSC commands are added
- Clear documentation of what commands exist
6. Processing Stats
Lines: 268-312
Contents:
ProcessingStatsstruct (lines 269-288) - timing/debugging statisticsProcessingStats::reset()(lines 291-293)ProcessingStats::log_if_slow()(lines 295-311) - conditional performance logging
Proposed file: src/stats.rs
Dependencies:
// No dependencies - uses only log crate
Challenges:
- Only used for debugging/profiling
- Could be feature-gated behind a
profilingfeature flag
Benefits:
- Separates debug instrumentation from core logic
- Could be conditionally compiled out for release builds
7. Saved Cursor and Alternate Screen (Keep in terminal.rs)
Lines: 243-265
Contents:
SavedCursorstruct (lines 243-253)AlternateScreenstruct (lines 256-265)
Recommendation: Keep in terminal.rs
Rationale:
- These are private implementation details of cursor save/restore and alternate screen
- Tightly coupled to Terminal's internal state
- No benefit from extraction
8. Handler Implementation (Keep in terminal.rs)
Lines: 1236-1904, 1906-2335
Contents:
impl Handler for Terminal- VT parser callback implementations- CSI handling, SGR parsing, DEC private modes
- Keyboard protocol, OSC handling, graphics protocol
Recommendation: Keep in terminal.rs (or consider splitting if file grows further)
Rationale:
- These are the core terminal emulation callbacks
- Heavily intertwined with Terminal's internal state
- Could potentially split into
terminal_csi.rs,terminal_sgr.rs, etc. but adds complexity
Recommended Extraction Order
src/cell.rs- No dependencies, foundational typessrc/terminal_commands.rs- No dependencies, simple enumssrc/stats.rs- No dependencies, debugging utilitysrc/color.rs- Depends oncell.rs, self-contained logicsrc/scrollback.rs- Depends oncell.rs, self-contained data structuresrc/mouse.rs- Self-contained enums, may need refactoring for encode function
Example: cell.rs Implementation
//! Terminal cell and color types.
/// A single cell in the terminal grid.
#[derive(Clone, Copy, Debug)]
pub struct Cell {
pub character: char,
pub fg_color: Color,
pub bg_color: Color,
pub bold: bool,
pub italic: bool,
/// Underline style: 0=none, 1=single, 2=double, 3=curly, 4=dotted, 5=dashed
pub underline_style: u8,
/// Strikethrough decoration
pub strikethrough: bool,
/// If true, this cell is the continuation of a wide (double-width) character.
pub wide_continuation: bool,
}
impl Default for Cell {
fn default() -> Self {
Self {
character: ' ',
fg_color: Color::Default,
bg_color: Color::Default,
bold: false,
italic: false,
underline_style: 0,
strikethrough: false,
wide_continuation: false,
}
}
}
/// Terminal colors.
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub enum Color {
#[default]
Default,
Rgb(u8, u8, u8),
Indexed(u8),
}
/// Cursor shape styles (DECSCUSR).
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub enum CursorShape {
#[default]
BlinkingBlock,
SteadyBlock,
BlinkingUnderline,
SteadyUnderline,
BlinkingBar,
SteadyBar,
}
Impact on lib.rs
After extraction, lib.rs would need:
pub mod cell;
pub mod color;
pub mod mouse;
pub mod scrollback;
pub mod stats;
pub mod terminal;
pub mod terminal_commands;
// ... existing modules ...
And terminal.rs would add:
use crate::cell::{Cell, Color, CursorShape};
use crate::color::ColorPalette;
use crate::mouse::{MouseEncoding, MouseTrackingMode};
use crate::scrollback::ScrollbackBuffer;
use crate::stats::ProcessingStats;
use crate::terminal_commands::{Direction, TerminalCommand};
Testing Opportunities
Extracting these modules enables focused unit tests:
- cell.rs: Default cell values, wide_continuation handling
- color.rs:
parse_color_spec()for various formats, palette indexing, RGBA conversion - mouse.rs: Encoding tests for X10, SGR, URXVT formats, tracking mode filtering
- scrollback.rs: Ring buffer push/get/wrap, capacity limits, clear behavior
Notes
- The
Terminalstruct itself (lines 428-512) should remain interminal.rsas the central state container - Private helper structs like
SavedCursorandAlternateScreenshould stay interminal.rs - The
Handlertrait implementation spans ~600 lines but is core terminal logic - Consider feature-gating
ProcessingStatsbehind#[cfg(feature = "profiling")]