https://github.com/masak1yu/winxmerge
WinXMerge is an Open Source differencing and merging tool for MacOS and Linux.
https://github.com/masak1yu/winxmerge
diff linux macos merge
Last synced: 3 months ago
JSON representation
WinXMerge is an Open Source differencing and merging tool for MacOS and Linux.
- Host: GitHub
- URL: https://github.com/masak1yu/winxmerge
- Owner: masak1yu
- Created: 2026-03-17T02:52:23.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-31T20:10:06.000Z (3 months ago)
- Last Synced: 2026-04-01T16:42:24.840Z (3 months ago)
- Topics: diff, linux, macos, merge
- Language: Rust
- Homepage:
- Size: 583 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# WinXMerge
[](https://github.com/masak1yu/winxmerge/actions/workflows/ci.yml)
A cross-platform file diff comparison and merge tool inspired by WinMerge, built with Rust + Slint UI.

## Features
### File Comparison (2-way)
- Block-level diff grouping: consecutive changes merged into one diff block (WinMerge-style)
- Line-level diff display (additions/deletions/changes/moves with color coding)
- Word-level (character-level) diff display for modified lines
- Diff navigation (first/previous/next/last diff block)
- Merge operations (block-level copy: left→right / right→left, copy & advance, copy all)
- Two-pane display with inline diff markers
- Location pane (minimap of diff positions)
- Automatic detection of moved lines (blue highlight)
- Synchronized left/right scrolling
- Click line numbers to select diff blocks
### 3-way Merge
- Three-pane display (Left / Base / Right)
- WinMerge-style Make3wayDiff overlap-grouping algorithm
- Automatic detection of changes from base file
- Conflict highlighting (red) with L/R buttons for conflict resolution
- Conflict navigation (next/previous)
- Copy & advance, copy all toolbar buttons
- Auto-merge when both sides have identical changes
- Inline editing with F5 rescan (VecModel as authoritative source)
- Save dropdown: save Left / Middle / Right individually
### Folder Comparison
- Recursive directory comparison with tree-style indentation
- File status display (identical / different / one-side only)
- Left/right modification timestamps
- Automatic .gitignore pattern loading (.git directories auto-excluded)
- File extension filter
- Double-click to open file diff view
- Right-click context menu (copy to left/right, delete)
- "< Back" button to return to folder view
- **Status filter bar**: All / Identical / Different / Left only / Right only filter buttons above the file list
- **Column sort**: click any column header (Name / Status / Left Size / Right Size / Left Modified / Right Modified) to sort; click again to toggle ascending/descending (▲▼ indicator)
### Tabs
- Manage multiple comparisons with tabs
- Each tab maintains independent state
- Cmd+T to create new tab, Cmd+W to close
### Diff Detail Pane
- Bottom pane showing the selected diff block's left/right content
- Top = left (removed), Bottom = right (added) with scrollable view
- Automatically updates when navigating between diffs
### Toolbar
- WinMerge-style icon toolbar with SVG icons
- Single row: New, Open, Save, Undo/Redo, Rescan, Options, Navigation, Copy, Copy & Advance, Copy All, Ignore WS/Case
- Hover hints shown in status bar
- Toggle buttons for Ignore Whitespace / Ignore Case
### Syntax Highlighting
- Line-level highlighting via tree-sitter
- Supported languages: Rust, JavaScript, Python, JSON, C, C++, Go, TypeScript, TSX, Ruby, Java, C#, YAML, TOML, Markdown
- Automatic file type detection
- Toggle on/off in options
### Undo / Redo
- Undo and redo merge operations
- Cmd+Z / Cmd+Shift+Z
### Diff Options
- Ignore whitespace
- Ignore case
- Ignore blank lines
- Ignore line ending differences
- Toggle moved line detection
### Filters
- **Line filters**: Exclude lines matching regex patterns from comparison (e.g., comments, timestamps)
- **Substitution filters**: Apply regex find/replace before comparison (e.g., normalize dates, version numbers)
- Multiple rules support via pipe-separated patterns
- Configured via Edit → Options... → Filters
- Settings persisted across sessions
### Encoding
- Automatic character encoding detection (UTF-8, UTF-16, Shift_JIS, etc.)
- BOM support
- Preserves original encoding when saving
### Search & Replace
- Text search (match count display, previous/next navigation)
- Replace / Replace All
- Available in both 2-way and 3-way diff views
### Go to Line
- Jump to a specific line number (Cmd+G)
### Bookmarks
- Toggle bookmarks on diff lines (Cmd+M)
- Navigate between bookmarks (F2 / Navigate menu)
### Keyboard Shortcuts
| Shortcut | Action |
|----------|--------|
| Cmd+S | Save left file |
| Cmd+F | Toggle search & replace |
| Cmd+G | Go to line |
| Cmd+M | Toggle bookmark |
| Cmd+Z | Undo |
| Cmd+Shift+Z | Redo |
| Cmd+T | New tab |
| Cmd+W | Close tab |
| Cmd+N | New comparison |
| Alt+↓ | Next diff |
| Alt+↑ | Previous diff |
| Alt+Home | First diff |
| Alt+End | Last diff |
| F2 | Next bookmark |
| F5 | Rescan files |
### Open in External Editor
- Open left or right file in system default editor (File menu)
- Custom editor command configurable in settings
### Plugin System
- Execute external commands with file path placeholders ({LEFT}, {RIGHT})
- Plugins configured in settings.json
- Available via Plugins menu
### Auto-rescan
- Automatic file change detection (polls every 500ms)
- Re-runs diff when files are modified externally
- Skips reload while user has unsaved inline edits (prevents data loss)
- Toggle via Edit → Options... → Auto-rescan
### Accessibility
- ARIA-compatible accessible roles and labels on key UI components
- Screen reader support for diff view and folder comparison
### Internationalization (i18n)
- Japanese / English UI switching (Edit → Options... → Appearance → Language)
- Full translation support for menus, toolbar, dialogs, and status bar
### Theme Switching
- Light / Dark theme switching (Edit → Options... → Appearance)
- All widgets automatically follow theme via Slint Palette integration
- Diff colors and syntax highlighting colors optimized per theme
- Settings persisted across sessions
### Built-in File Browser
- Native-dialog-independent file/folder picker (works on WSL2 and environments without GTK)
- Directory navigation with folder/file icons, parent button, and editable path bar
- Falls back automatically when the system file dialog is unavailable
### ZIP Archive Comparison
- Compare `.zip` files as virtual folders showing added/removed/changed entries
- CRC + size based change detection per entry
### CSV / TSV Comparison
- Compare `.csv` and `.tsv` files with cell-level diff table display
- Auto-detects delimiter (comma vs tab) independently per file
- Handles quoted fields with embedded delimiters and newlines
- Drag column header borders to resize columns
- Inline cell editing with undo/redo (Cmd+Z / Cmd+Shift+Z)
- Save edited table as CSV (Cmd+S), with Save As dialog for new documents
- F5 rescan recomputes diff from edited cells (VecModel as authoritative source)
- Delimiter mismatch warning when comparing .csv vs .tsv files
### Excel / Spreadsheet Comparison
- Compare `.xlsx`, `.xls`, `.xlsm`, `.ods` files with table-view cell diff display
- Changed cells highlighted; sheet selector for multi-sheet files
### Image Comparison
- Pixel-level comparison for PNG, JPEG, GIF, BMP, WebP, TIFF, ICO
- Side-by-side left/right panels + diff overlay (changed pixels in red, identical pixels in gray)
- Continuous zoom slider (10–400%) with Fit mode and diff panel toggle
- **Blend slider** (0–100%): overlay changed-pixel highlights directly on the left/right panels at adjustable opacity
### Diff Detail Pane (WinMerge-style)
- Shows only the currently selected diff block (not the whole file)
- Left panel for removed/modified lines, Right panel for added/modified lines
- Single panel when only one side has changes; both panels with inner resize handle when both sides differ
- Character-level background highlighting on changed segments within modified lines
- Pane height resizable by dragging the top handle; inner split resizable by dragging between panels
### Diff Comments
- Add per-block notes in the detail pane (Note field)
- Comments persisted to session and embedded in HTML / Excel export reports
- **Export All Comments**: File → Export All Comments (CSV/JSON)... — collects all comments across all tabs and saves as CSV or JSON
### App Icon
- Custom "Diff Panels" icon (cross-platform): embedded in the Windows executable (.ico) and macOS bundle (.icns)
### Diff Stats Bar Graph
- Status bar shows proportional mini bar graph (green=added, red=removed, yellow=modified) alongside `+A -R ~M` counts
### Keyboard Shortcuts Dialog
- Help → Keyboard Shortcuts: scrollable reference of all shortcuts grouped by File / Navigation / Merge / View
### Session Persistence Improvements
- Tabs restored with encoding, EOL type, tab width, diff-only mode, status filter, and diff comments
### View Menu Enhancements
- **Zoom In / Zoom Out / Reset Zoom**: adjust editor font size from the View menu (range 8–32pt)
- **Wrap Lines**: toggle line wrapping at the window edge (View → Wrap Lines, default off)
- Row height adapts to font size in both normal and wrap modes
### Window Resizing
- Window is now properly resizable (initial size 1200×800, minimum 600×400)
- Diff view panes use proportional layout (no fixed-width binding loops)
### Inline Editing (WinMerge-style)
- Edit text directly in diff panes — always in aligned Ghost-line view (no separate edit mode)
- Enter to insert new line (Ghost line added to other pane for alignment)
- Backspace at start of empty line to delete
- Arrow keys (Up/Down) to move between editable rows
- F5 to rescan (recompute diff from edited content)
- Undo/Redo support for all edit operations
### New Blank Document
- File → New → Text: create empty 2-way comparison document
- File → New → Table: create empty CSV/TSV comparison document (10x5 initial grid, editable immediately)
- File → New (3-pane) → Text / Table: create empty 3-way comparison
- Toolbar "New" button with dropdown for type selection
### Save As Dialog (WinMerge-style)
- In-app file browser dialog with directory listing, navigation, and filename input
- Shown when saving documents without file paths (new/clipboard)
- Directory defaults to current working directory
- On quit with unsaved changes: Save / Don't Save / Cancel (cancel aborts quit)
### Git Difftool Integration
- Single-instance mode via Unix domain socket IPC
- `git difftool` opens diffs as tabs in the existing window
- Multiple file pairs (2+) displayed as a virtual folder comparison view
- Double-click a file in the folder view to open detailed diff in a new tab
### Other
- WinMerge-style initial file selection dialog (with recent files list)
- WinMerge-style options dialog (Edit → Options...)
- Right-click context menu (copy, merge, navigation)
- Unsaved changes confirmation dialog (WinMerge-style Save/Don't Save/Cancel)
- HTML diff report export (File → Export HTML Report...) with embedded diff comments (also included in Print)
- Excel diff report export (File → Export Excel (.xlsx)...) with color-coded rows and comments column
- Native menu bar (macOS / Windows)
- Settings persistence (~/.config/winxmerge/settings.json)
- Performance optimizations for large files
- GitHub Actions CI (build, test, lint on Ubuntu / macOS / Windows)
- Automated release builds for Linux, macOS (aarch64), and Windows
## Tech Stack
| Component | Technology |
|-----------|-----------|
| Language | Rust 1.94.0 |
| UI Framework | [Slint](https://slint.dev/) 1.15 |
| Diff Algorithm | [similar](https://crates.io/crates/similar) |
| Syntax Highlighting | [tree-sitter](https://crates.io/crates/tree-sitter) |
| File Dialog | [rfd](https://crates.io/crates/rfd) |
| Encoding Detection | [chardetng](https://crates.io/crates/chardetng) + [encoding_rs](https://crates.io/crates/encoding_rs) |
| Clipboard | [arboard](https://crates.io/crates/arboard) |
| Settings Persistence | [serde](https://crates.io/crates/serde) + [serde_json](https://crates.io/crates/serde_json) |
| ZIP Comparison | [zip](https://crates.io/crates/zip) |
| Excel Comparison | [calamine](https://crates.io/crates/calamine) |
| Excel Export | [rust_xlsxwriter](https://crates.io/crates/rust_xlsxwriter) |
| Image Comparison | [image](https://crates.io/crates/image) |
| WASM Build | [wasm-bindgen](https://crates.io/crates/wasm-bindgen) + [trunk](https://trunkrs.dev/) |
## Web Version (WASM)
**Live: https://winxmerge.app**
WinXMerge can be built as a WebAssembly app for deployment to Cloudflare Pages.
The web version supports text input, file upload, clipboard paste, and diff navigation with stats. Desktop-only features (file dialogs, syntax highlighting, folder compare, etc.) are excluded via `cfg(not(target_arch = "wasm32"))` conditional compilation — the desktop build is unaffected.
### Build
```bash
# Install WASM target and trunk
rustup target add wasm32-unknown-unknown
cargo install trunk
# Development server
trunk serve
# Production build (outputs to dist/)
trunk build --release
```
Deploy the `dist/` directory to Cloudflare Pages.
## Setup
### Prerequisites
- [asdf](https://asdf-vm.com/) installed
- macOS / Linux / Windows (WSL)
### Getting Started
```bash
# Clone the repository
git clone git@github.com:masak1yu/winxmerge.git
cd winxmerge
# Install Rust via asdf
asdf plugin add rust
asdf install
# Build
cargo build
# Run tests
cargo test
# Launch the app
cargo run
# 2-way comparison
cargo run -- file1.txt file2.txt
# 3-way merge
cargo run -- base.txt left.txt right.txt
```
## Git Integration
WinXMerge can be used as a `git difftool` / `git mergetool`.
### difftool Setup
```bash
cargo build --release
cp target/release/winxmerge ~/.local/bin/
git config --global diff.tool winxmerge
git config --global difftool.winxmerge.cmd 'winxmerge "$LOCAL" "$REMOTE"'
git config --global difftool.prompt false
```
### mergetool Setup (3-way merge)
```bash
git config --global merge.tool winxmerge
git config --global mergetool.winxmerge.cmd 'winxmerge "$BASE" "$LOCAL" "$REMOTE"'
git config --global mergetool.winxmerge.trustExitCode true
```
### Usage
```bash
# View working tree changes
git difftool
# Diff a specific file
git difftool -- path/to/file.rs
# Diff between branches
git difftool main..feature-branch
# Resolve merge conflicts
git mergetool
```
### Single-Instance Tab Mode
When multiple files are changed, `git difftool` invokes WinXMerge once per file.
WinXMerge uses IPC (Unix domain socket) to detect a running instance and opens
subsequent diffs as new tabs in the existing window instead of spawning separate processes.
## Project Structure
```
winxmerge/
├── Cargo.toml
├── build.rs # Slint build configuration
├── .tool-versions # asdf version management
├── ui/
│ ├── main.slint # Main window
│ ├── theme.slint # Theme color definitions (light/dark)
│ ├── icons/ # SVG toolbar icons
│ ├── dialogs/
│ │ ├── open-dialog.slint # File/folder selection dialog
│ │ ├── file-browser.slint # Built-in file browser (WSL2-safe)
│ │ ├── save-confirm-dialog.slint # Save confirmation dialog (WinMerge-style)
│ │ ├── new-table-dialog.slint # New table type selection dialog
│ │ ├── options-dialog.slint # Options dialog
│ │ └── shortcuts-dialog.slint # Keyboard shortcuts reference dialog
│ └── widgets/
│ ├── diff-view.slint # 2-way diff display widget
│ ├── diff-view-3way.slint # 3-way merge display widget
│ ├── folder-view.slint # Folder comparison widget (with status filter)
│ ├── tab-bar.slint # Tab bar widget
│ ├── excel-view.slint # Excel cell diff table view
│ └── image-view.slint # Image comparison widget (continuous zoom)
├── src/
│ ├── main.rs # Entry point, CLI argument handling
│ ├── app.rs # Application state management (tab support)
│ ├── encoding.rs # Encoding detection and conversion
│ ├── export.rs # HTML/CSV/patch report export (with comment support)
│ ├── highlight.rs # Syntax highlighting (15 languages)
│ ├── settings.rs # Settings persistence (SessionEntry with full tab state)
│ ├── archive.rs # ZIP archive comparison
│ ├── excel.rs # Excel file comparison (calamine)
│ ├── image_compare.rs # Image comparison (pixel-level diff)
│ ├── diff/
│ │ ├── engine.rs # 2-way diff engine
│ │ ├── three_way.rs # 3-way merge engine
│ │ └── folder.rs # Recursive folder comparison
│ └── models/
│ ├── diff_line.rs # Diff line data model
│ └── folder_item.rs # Folder comparison item model
├── translations/ # Translation files (gettext .po)
│ └── ja/LC_MESSAGES/ # Japanese translations
└── testdata/ # Test sample files
```
## Usage
1. Launch the app with `cargo run`
2. Enter left/right file or folder paths in the initial dialog and click "Compare"
- For 3-way merge: check "3-way merge" and specify a base file
- Re-open recent files from the list with one click
3. **Diff navigation:** Use ◀ Prev / Next ▶ toolbar buttons or Alt+↓/↑
4. **Merge:** Use Copy → / ← Copy buttons, or inline ▶ / ◀ buttons between diff lines
5. **3-way conflict resolution:** Click L / R buttons on red (conflict) lines to choose left or right
6. **Undo:** Cmd+Z to undo operations
7. **Search:** Cmd+F to show the search & replace bar
8. **Tabs:** Cmd+T for a new tab, manage multiple comparisons in parallel
9. **Options:** Edit → Options... to configure settings
## License
This project is distributed under the [Slint Royalty-Free Desktop, Mobile, and Web Applications License v2.0](https://slint.dev/terms-and-conditions#royalty-free).
Since this project uses the Slint UI framework, the following conditions apply:
- Distribution as desktop / mobile / web applications is royalty-free
- Embedded system use is not covered
- Slint attribution (AboutSlint widget or web badge) is required