A terminal-based user-friendly diff tool written in Rust.
Note
This is a project submitted in partial fulfillment of the requirements for the online CS50 course, "Introduction to Computer Science", at Harvard University. Github copilot with Anthropic Claude Haiku 4.5 model was used for generating the project documentation and initial prototyping for faster development.
Rusty Diff is a command-line tool designed to compare two files and display the differences between them in a user-friendly manner. It is written in Rust, a systems programming language that provides memory safety and concurrency without sacrificing performance. It provides a simple and intuitive interface for users to compare files and directories, making it an ideal tool for developers and system administrators. It uses the widely-used and standard Git diff and GNU diff utilities to compare files under the hood.
Rusty Diff requires the following dependencies to be installed on your system:
- Rust
- Git
- GNU diffutils (already installed on most Linux distributions)
Rusty Diff uses the following Rust crates:
anyhow(version 1.0.100): for error handlingclap(version 4.5.53): for command-line argument parsing. Thecargoandderivefeatures have also been enabled.crossterm(version 0.29.0): for terminal manipulation.ratatui(version 0.29.0): for terminal user interface.regex(version 1.12.2): for regular expression matching.syntect(version 5.3.0): for syntax highlighting support.
If you are planning to contribute to the project, you will also need to install the following development dependencies:
pretty-assertions(version 1.4.1): for pretty assertions in tests.
Clone the repository using the following command:
git clone https://github.com/shayanmoosavi/rustydiff.gitNavigate to the project directory and build the project using Cargo:
cd rustydiff
cargo build --releasecopy the binary to a directory in your PATH:
sudo cp target/release/rustydiff /usr/local/bin/Verify that Rusty Diff is installed correctly by running the following command:
rustydiff --version- Robust diff handling with graceful fallback. (Git diff with GNU diff as a fallback)
- Syntax highlighting support for various programming languages.
- Interactive and user-friendly interface with keybindings reference at the bottom of the screen.
- Comfortable and ergonomic keybindings. (both Vim-like and traditional)
Run Rusty Diff with the following command:
rustydiff file1 file2where file1 and file2 are the paths to the files you want to compare.
The project has the following directory structure:
.
├── Cargo.toml
├── DOCUMENTATION.md
├── README.md
└── src
├── diff
│ ├── models.rs
│ ├── parser.rs
│ └── utils.rs
├── diff.rs
├── lib.rs
├── main.rs
├── syntax
│ └── highlighter.rs
├── syntax.rs
├── ui
│ ├── app.rs
│ ├── events.rs
│ ├── renderers.rs
│ └── utils.rs
└── ui.rs
It consists of three main modules:
diff: Is responsible for handling the diff logic, parsing the output, and contains the core data models.syntax: Provides support for syntax highlighting using thesyntectcrate.ui: Is responsible for application state management, event handling, and rendering the user interface.
Data flow
The program accepts two files as input, runs the diff command, parses the output, and generates a DiffResult object. A diagram of the data flow is shown below:
Files → run_diff() → Raw output → parse_unified_diff() → DiffResult
The project root contains:
Cargo.toml: Contains the project dependencies and the standard cargo project metadata.src: Contains the source code of the project.DOCUMENTATION.md: Contains the project documentation.README.md: Contains the project README.LICENSE: Contains the project license.
The crate root which is the src directory contains:
main.rs: The main entry point of the application.lib.rs: Contains the module declarations and re-exports.diff.rs: Contains the submodule declarations for the diff module.ui.rs: Contains the submodule declarations for the ui module.syntax.rs: Contains the submodule declarations for the syntax module.
The diff module contains:
models.rs: Contains the core data structures and types used in the project.parser.rs: The parser submodule of the diff module which is responsible for parsing the unified diff output.utils.rs: Contains the utility wrapper functions to execute external commands.
The syntax module contains:
highlighter.rs: A thin wrapper module around thesyntectcrate for syntax highlighting.
The ui module contains:
app.rs: The app submodule of the ui module which is responsible for application state management.events.rs: The events submodule of the ui module which is responsible for handling user events.renderers.rs: The renderers submodule of the ui module which is responsible for rendering the UI.utils.rs: Contains the utility functions for the ui module.
For a more comprehensive documentation, please refer to the DOCUMENTATION.md file. You could also run cargo doc --open in the project's root directory to view the generated documentation.
To contribute to this project, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and commit them.
- Push your changes to your forked repository.
- Create a pull request to the main repository.
This project is licensed under the GNU General Public License v3.0. For more information, please refer to the LICENSE file.
- Thanks to the Rust community for their contributions to the crates used in this project.