Skip to main content

diffs_rs/
lib.rs

1//! A terminal diff viewer engine for Ratatui applications.
2//!
3//! This crate provides the `diffs` command-line viewer and the [`engine::Engine`] it is built
4//! on. An `Engine` opens one review (a Git patch, two files, or two Git commits), loads and
5//! colors it on background threads, and draws into any [`ratatui::layout::Rect`]. The host keeps
6//! ownership of the terminal, input, and layout.
7//!
8//! ```no_run
9//! use std::{sync::mpsc, time::Duration};
10//!
11//! use diffs_rs::engine::{Engine, Input, Options};
12//! use ratatui::crossterm::event::{self, Event, KeyCode};
13//!
14//! fn main() -> anyhow::Result<()> {
15//!     let mut terminal = ratatui::init();
16//!     // The engine sends a hint on this channel when background work is ready.
17//!     let (wake, woken) = mpsc::sync_channel(1);
18//!     let input = Input::Patch("changes.patch".into());
19//!     let mut engine = Engine::open(input, Options::default(), wake)?;
20//!
21//!     let result = (|| -> anyhow::Result<()> {
22//!         loop {
23//!             let _ = woken.try_recv();
24//!             engine.poll()?;
25//!             if engine.needs_draw() {
26//!                 let mut drawn = Ok(());
27//!                 terminal.draw(|frame| {
28//!                     let area = frame.area();
29//!                     drawn = engine.draw(frame, area);
30//!                 })?;
31//!                 drawn?;
32//!                 engine.after_draw();
33//!             }
34//!             if event::poll(Duration::from_millis(16))? {
35//!                 let event = event::read()?;
36//!                 if matches!(&event, Event::Key(key) if key.code == KeyCode::Char('q')) {
37//!                     return Ok(());
38//!                 }
39//!                 engine.handle_event(event, true)?;
40//!             }
41//!         }
42//!     })();
43//!
44//!     // Joins the background workers and reports cleanup errors.
45//!     let closed = engine.close();
46//!     ratatui::restore();
47//!     result.and(closed)
48//! }
49//! ```
50//!
51//! The [embedding guide](https://github.com/plannotator/diffs-rs/blob/main/docs/embedding.md)
52//! covers the host loop, focus, source coordinates, reading tools, and shutdown.
53
54pub mod app;
55mod cleanup;
56pub mod engine;
57pub mod geometry;
58pub mod highlight;
59pub mod ingest;
60pub mod input;
61pub mod model;
62pub mod projection;
63pub mod reading;
64pub mod render;
65pub mod source;
66mod source_spans;
67pub mod storage;
68pub mod text;
69pub mod theme;
70mod tree;
71pub mod view;
72mod wake;
73
74#[cfg(feature = "regex-census")]
75mod regex_census;
76
77#[cfg(feature = "owner-census")]
78pub mod owner_census;
79
80#[cfg(feature = "delivery-trace")]
81pub mod delivery_trace;
82
83#[macro_export]
84macro_rules! delivery_event {
85    ($kind:literal, $a:expr, $b:expr) => {
86        #[cfg(feature = "delivery-trace")]
87        $crate::delivery_trace::record($kind, $a as u64, $b as u64);
88    };
89}