Conventions and workflow for contributing to TerminalG.
- Follow Rust API Guidelines
- Use
cargo fmtbefore committing (automatic formatting) - Pass
cargo clippychecks (linting) - Add comments for non-obvious logic
// 1. Module and crate imports
mod submodule;
use std::path::Path;
use crate::other::module;
// 2. Type definitions
pub struct MyStruct { ... }
pub enum MyEnum { ... }
// 3. Trait implementations
impl MyStruct { ... }
impl Trait for MyStruct { ... }
// 4. Tests (if in same file)
#[cfg(test)]
mod tests { ... }Every public item should have a doc comment:
/// Brief description.
///
/// Longer explanation if needed.
///
/// # Examples
///
/// ```
/// // Example code
/// ```
///
/// # Errors
///
/// Returns error if...
pub fn my_function() -> Result<()> {
// implementation
}- Use
anyhow::Result<T>for functions that can fail - Use
.context("description")to add context to errors - Avoid
.unwrap()and.expect()in library code
use anyhow::{Context, Result};
pub fn load_file(path: &Path) -> Result<String> {
std::fs::read_to_string(path)
.context(format!("Failed to read file: {:?}", path))
}- Feature:
feature/description(e.g.,feature/url-recognition) - Fix:
fix/issue-name(e.g.,fix/terminal-crash) - Docs:
docs/something(e.g.,docs/api-reference) - Refactor:
refactor/what(e.g.,refactor/settings-system)
- Use imperative mood: "Add feature" not "Added feature"
- Keep commits focused and atomic
- Reference issues if applicable: "Fix #123"
# Bad
git commit -m "stuff"
git commit -m "Fixed some bugs and added new features"
# Good
git commit -m "Add URL recognition in terminal output"
git commit -m "Fix terminal rendering crash on long lines"- Create feature branch:
git checkout -b feature/description - Make changes and commit regularly
- Push:
git push origin feature/description - Create PR with description of changes
- Ensure all checks pass (build, tests, lint)
- Merge to main
# Check for compilation errors
cargo check
# Run tests
cargo test
# Format code
cargo fmt
# Lint code
cargo clippy -- -D warnings# Debug build (default, fast compile, slow runtime)
cargo build
# Release build (slow compile, fast runtime)
cargo build --release
# Minimal build (check only, no binary)
cargo check- Read the phase section in
IMPLEMENTATION-PLAN.md - Create feature branch:
git checkout -b feature/phase-X-description - Create module stubs if needed
- Write tests first (TDD approach)
- Implement functionality
- Ensure tests pass:
cargo test - Check lints:
cargo clippy - Update CLAUDE.md progress
- Create commit(s) for reviewability
- Run
cargo checkfrequently (catches errors early) - Keep functions small and focused
- Add tests as you go, not at the end
- Log important operations:
tracing::info!("message")
At each phase checkpoint:
- All tests passing:
cargo test - No compiler warnings:
cargo check - Clippy clean:
cargo clippy - All phase items completed
- Update CLAUDE.md with status
- Git commit with phase tag:
git commit -m "Complete Phase X" - Git tag:
git tag phase-X-complete
Use the tracing crate for debug output:
use tracing::{info, debug, warn, error};
info!("Important operation completed");
debug!("Detailed debug information: {:?}", value);
warn!("Warning about potential issue");
error!("Error occurred: {}", err);Set log level when running:
# Info and higher
cargo run
# Debug and higher
RUST_LOG=debug cargo run
# Specific module
RUST_LOG=terminalg::terminal=debug cargo run
# Multiple modules
RUST_LOG=terminalg::settings=debug,terminalg::terminal=info cargo runUse conditional compilation for platform-specific code:
#[cfg(target_os = "macos")]
fn macos_specific() {
// macOS code
}
#[cfg(target_os = "linux")]
fn linux_specific() {
// Linux code
}
#[cfg(target_os = "windows")]
fn windows_specific() {
// Windows code
}
#[cfg(unix)]
fn unix_code() {
// Unix (macOS + Linux)
}
#[cfg(not(windows))]
fn non_windows() {
// Not Windows
}Test on all platforms before merge:
# macOS
cargo test
# Linux (if available)
docker run --rm -v $(pwd):/work -w /work rust:latest cargo test
# Windows (if available)
cargo testWorkspace Navigation
Ctrl+1- Focus terminal paneCtrl+2- Focus viewer paneCtrl+Tab- Next workspace tabCtrl+Shift+Tab- Previous workspace tabCtrl+N- New workspaceCtrl+W- Close workspace
Terminal
Ctrl+C- Send interruptCtrl+L- Clear screenCmd+K(macOS) /Ctrl+L- Clear scrollbackCmd+F(macOS) /Ctrl+F- Search output
Viewers
+/-- Zoom in/outCtrl+0- Reset zoomSpace- Fit to window
General
Ctrl+,- Open settingsCtrl+Shift+T- Cycle themesCtrl+Shift+L- Toggle light/dark theme
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_description() {
// Arrange
let input = "test";
// Act
let result = function_under_test(input);
// Assert
assert_eq!(result, "expected");
}
}Run tests:
# Run all tests
cargo test
# Run specific test
cargo test test_name
# Run with output
cargo test -- --nocapture
# Run only unit tests
cargo test --lib
# Run integration tests
cargo test --test '*'Use profiling for performance-critical sections:
# Flamegraph (requires cargo-flamegraph)
cargo install flamegraph
cargo flamegraph --release -- <args>
# Valgrind (Linux)
valgrind ./target/release/terminalg- Use
cargo auditto check for vulnerable dependencies - Validate user input at boundaries
- Use types to enforce correctness (leverage Rust's type system)
- Avoid
unsafecode unless absolutely necessary
cargo add crate_name
# or
cargo add crate_name@version
# or manually edit Cargo.toml and run cargo buildcargo updatecargo doc --opencargo bench # if benchmarks existRead the error message carefully - Rust's compiler is excellent at explaining lifetime issues.
- Run with
-- --nocaptureto see println output - Run single test:
cargo test test_name -- --nocapture - Use debugger:
rust-gdb target/debug/terminalg
- Use
cargo checkinstead ofcargo buildduring development - Use incremental compilation:
CARGO_INCREMENTAL=1 - Consider splitting into more crates if it gets very large
- Test on each platform before committing
- Use CI/CD to catch platform issues
- Check Cargo features for platform dependencies