https://github.com/elgar328/nfd2nfc
macOS NFD-to-NFC filename converter with TUI and background watcher
https://github.com/elgar328/nfd2nfc
file-watcher filename-conversion macos nfc nfd tui unicode-normalization
Last synced: 13 days ago
JSON representation
macOS NFD-to-NFC filename converter with TUI and background watcher
- Host: GitHub
- URL: https://github.com/elgar328/nfd2nfc
- Owner: elgar328
- License: mit
- Created: 2025-02-04T13:32:26.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-02-06T02:00:58.000Z (17 days ago)
- Last Synced: 2026-02-06T02:48:44.281Z (17 days ago)
- Topics: file-watcher, filename-conversion, macos, nfc, nfd, tui, unicode-normalization
- Language: Rust
- Homepage:
- Size: 817 KB
- Stars: 6
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# nfd2nfc
[](https://github.com/elgar328/nfd2nfc/releases)
[](https://github.com/elgar328/nfd2nfc/actions/workflows/ci.yml)
[](https://github.com/elgar328/nfd2nfc#license)
[](docs/README.ko.md)
A macOS tool that watches directories and converts NFD filenames to NFC in real time, ensuring cross-platform compatibility.
## What is NFD/NFC?
Unicode has two main ways to represent composed characters such as Korean Hangul, accented Latin (é, ü, ñ), Japanese kana (が, ぱ), and more:
- **NFC** (Composed): One codepoint per character — `가` = `U+AC00`
- **NFD** (Decomposed): Base + combining marks — `가` = `U+1100 U+1161`
macOS stores filenames in NFD, while Windows and Linux use NFC. This mismatch causes problems when sharing files across platforms:
- Hangul syllables appear as decomposed jamo (e.g., 한글 → ㅎㅏㄴㄱㅡㄹ)
- Accented characters may render or sort incorrectly
- Git sees identical files as untracked or modified
- Cloud sync and archive tools fail to match paths
**nfd2nfc** provides an interactive TUI and a background watcher service that handles conversion automatically.
## Features
- **Real-time monitoring** — Converts NFD filenames to NFC as soon as they appear
- **Flexible watch paths** — Mix `watch`/`ignore` actions with `recursive`/`children` modes to control exactly which directories are monitored
- **Manual conversion** — Browse the filesystem and convert names between NFD and NFC on the spot
- **Log viewer** — Review past watcher logs or follow new entries live
- **Intuitive controls** — Every keybinding is shown on screen, and full mouse support is included
## Home

The Home tab displays the current watcher service status and provides controls to start, stop, or restart it.
## Config

The Config tab manages which directories the watcher monitors. Each path entry has an action (`watch` or `ignore`), mode (`recursive` or `children`), and validation status.
## Logs

The Logs tab lets you browse past watcher logs and follow new entries in real time. Logs are stored in macOS system logs, and retention is managed by the OS.
## Browser

The Browser tab lets you inspect files and directories for their Unicode normalization form and convert them directly. The watcher only picks up newly created or modified files, so use this tab to convert any existing NFD names.
## Installation
Requires [Homebrew](https://brew.sh).
```bash
brew install elgar328/nfd2nfc/nfd2nfc
```
Then run it:
```bash
nfd2nfc
```
On first launch, the watcher service is automatically registered via `brew services`. After that, you can start and stop it from the app.
### Permissions
If macOS repeatedly prompts for folder access when the watcher converts files, grant **Full Disk Access** to the watcher binary:
1. Run `which nfd2nfc-watcher` to find the binary path
2. Open **System Settings → Privacy & Security → Full Disk Access**
3. Click `+`, press `Cmd+Shift+G`, paste the path from step 1, and add it
## Upgrading from v1
```bash
brew upgrade nfd2nfc
```
v2 replaces the previous CLI with a more user-friendly TUI. The config format (`~/.config/nfd2nfc/config.toml`) has changed as well, so you will need to re-add your watch paths in the Config tab after upgrading.
## Uninstallation
```bash
brew uninstall nfd2nfc
```
## License
[MIT](LICENSE)