Contributing

Author:

Rohit Goswami

Development setup

git clone https://github.com/TurtleTech-ehf/snapper
cd snapper
cargo build
cargo test

With pixi:

pixi run -e dev check

Running checks

cargo fmt --check
cargo clippy -- -D warnings
cargo test

Dogfood check (verify all docs pass formatting):

pixi run -e dev dogfood

Project structure

src/
  main.rs             -- Entry point, CLI dispatch, subcommand routing
  lib.rs              -- Public API: format_text(), FormatConfig, build_splitter()
  cli.rs              -- Clap derive CLI + subcommands (init, sdiff, git-diff, watch, lsp)
  config.rs           -- .snapperrc.toml serde-based config with per-format sections
  format.rs           -- Format enum + auto-detection from extension
  diff.rs             -- Unified diff output for --diff mode
  sdiff.rs            -- Sentence-level diff (snapper sdiff)
  git_diff.rs         -- Git-aware sentence diff (snapper git-diff)
  init.rs             -- Project initialization (snapper init)
  lsp.rs              -- LSP server (snapper lsp) via tower-lsp
  watch.rs            -- File watcher (snapper watch) via notify
  output.rs           -- JSON/SARIF output for --check mode
  abbreviations.rs    -- Multi-language abbreviation lists (en, de, fr, is, pl)
  reflow.rs           -- Core reflow engine (regions + splitter -> output)
  files.rs            -- File-level formatting utilities
  sentence/
    mod.rs            -- SentenceSplitter trait
    unicode.rs        -- UAX #29 + abbreviation merge + placeholder system
    neural.rs         -- nnsplit LSTM sentence detection (9 languages)
  parser/
    mod.rs            -- Region enum, FormatParser trait, pragma support
    org.rs            -- Org-mode parser
    latex.rs          -- LaTeX parser
    markdown.rs       -- Markdown parser
    rst.rs            -- reStructuredText parser
    plaintext.rs      -- Plaintext parser (everything is prose)
editors/
  vscode/             -- VS Code extension (LSP client)
tests/
  integration.rs      -- Integration tests (format, check, idempotency, stdin)
  fixtures/           -- Sample input/expected output pairs per format
vale/
  snapper/            -- Vale style rules for editor hints
site/                 -- Landing page (static HTML)
docs/
  orgmode/            -- Documentation source (org-mode)
  source/             -- Sphinx config + templates
  export.el           -- Batch org -> RST exporter

Commit conventions

Commits follow conventional commits, managed by cocogitto (cog):

feat:

new features

fix:

bug fixes

doc:

documentation changes

chore:

maintenance, dependency bumps

tst:

test changes

bld:

build system changes

Building documentation

pixi run -e docs docbld

Or manually:

emacs --batch -l docs/export.el
sphinx-build docs/source docs/build -b html

Adding a new format parser

  1. Create src/parser/yourformat.rs implementing the FormatParser trait

  2. Add the variant to Format enum in src/format.rs

  3. Wire it into format_text() in src/lib.rs

  4. Add extension mapping in Format::from_path()

  5. Add fixture pair in tests/fixtures/ (sample.fmt + expected.fmt)

  6. Add integration tests in tests/integration.rs

  7. Document in docs/orgmode/reference/formats.org