Skip to main content

rlsp_fmt/
lib.rs

1// SPDX-License-Identifier: MIT
2
3//! A Wadler-Lindig pretty-printing engine.
4//!
5//! Build a [`Doc`] tree that describes the *structure* of your output, then let
6//! the printer decide where to break lines based on the available width.  The
7//! core idea: [`group`] marks a subtree as a flat/break decision boundary — the
8//! printer tries to render it on one line and falls back to multi-line only when
9//! the content would exceed [`FormatOptions::print_width`].
10//!
11//! # Quick start
12//!
13//! ```
14//! use rlsp_fmt::{Doc, concat, group, indent, line, text, format, FormatOptions};
15//!
16//! // Build a document: "[" <items> "]"
17//! let doc = group(concat(vec![
18//!     text("["),
19//!     indent(concat(vec![line(), text("a"), text(","), line(), text("b")])),
20//!     line(),
21//!     text("]"),
22//! ]));
23//!
24//! let opts = FormatOptions { print_width: 80, ..Default::default() };
25//! assert_eq!(format(&doc, &opts), "[ a, b ]");
26//!
27//! // Narrow width forces the group to break.
28//! let opts_narrow = FormatOptions { print_width: 5, ..Default::default() };
29//! assert!(format(&doc, &opts_narrow).contains('\n'));
30//! ```
31//!
32//! See [`FormatOptions`] for all rendering controls.
33
34/// Intermediate representation types for the pretty-printing engine.
35pub mod ir;
36/// The Wadler-Lindig line-breaking printer.
37pub mod printer;
38
39pub use ir::{Doc, concat, flat_alt, group, hard_line, indent, join, line, text};
40pub use printer::format;
41
42/// Options that control how a document is rendered.
43#[derive(Debug, Clone)]
44pub struct FormatOptions {
45    /// Maximum line width before the printer breaks groups. Default: 80.
46    pub print_width: usize,
47    /// Number of spaces per indentation level (ignored when `use_tabs` is
48    /// true). Default: 2.
49    pub tab_width: usize,
50    /// Use tab characters instead of spaces for indentation. Default: false.
51    pub use_tabs: bool,
52}
53
54impl Default for FormatOptions {
55    fn default() -> Self {
56        Self {
57            print_width: 80,
58            tab_width: 2,
59            use_tabs: false,
60        }
61    }
62}