From d7396073ee804ab2f95e842417495a14c82ab741 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Tue, 22 Jun 2021 00:30:58 -0700 Subject: [PATCH] Expand readme and add screenshot --- README.md | 17 +++++++++++------ img/difftastic.png | Bin 0 -> 21003 bytes 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 img/difftastic.png diff --git a/README.md b/README.md index 88ac6f9d3..3dd6366ed 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ -# Difftastic +# It's Difftastic! -A language-aware word-level diff. +Difftastic is an experimental structured diff tool that compares files +based on their syntax. -``` -$ cargo run before.js after.js -$ cargo run --inline before.js after.js -``` +![screenshot](img/difftastic.png) + +It is very much unfinished. It works reasonably on very parenthesised +data (lisps, JSON), it works sometimes on other languages with +sufficient parentheses (Rust, JS), and falls back to a line-oriented +diff otherwise. + +See `config/syntax.toml` to see how languages are defined. ## Other Diff Techniques diff --git a/img/difftastic.png b/img/difftastic.png new file mode 100644 index 0000000000000000000000000000000000000000..4cbd884cecd9555bc25f64be43396df9d702a851 GIT binary patch literal 21003 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 literal 0 HcmV?d00001