Features
Category-based rules
Define categories with extensions, filters, and destinations in a simple YAML file.
Watch mode
Monitor directories in real-time and move files automatically as they appear.
Undo
Interactive batch picker to select and revert any past operation. Pass a batch ID to skip the picker.
Dry-run everywhere
--dry-run on move and undo — preview before committing.
Conflict strategies
rename, overwrite, skip, or hash_check — per category.
Powerful filters
Regex, glob, age, and size filters; not exclusion; composable any/all logic.
Wildcard extension
extensions: [all] matches any file type — combine with organize-by: "{ext}" for a catch-all sorter.
organize-by templates
Build subdirectory structures with tokens: {ext}, {mod-year}, {mod-month}, {size-range}, and more.
Rich rename tokens
Name transforms, system info, timestamps, hashes, and sequences — e.g. {mod-date}_{name-slug}.{ext}.
Action control
move, copy, or symlink per category — back up or link files without touching the originals.
Rename at destination
Rename files on arrival using the token engine: rename: "{mod-date}_{name}.{ext}".
TUI config editor
movelooper edit opens a two-panel TUI editor with undo, redo, and validation on save.
Template scaffolding
Bootstrap a new config from a built-in template in the TUI editor: movelooper edit -o movelooper.yaml.
Config imports
Split categories across multiple YAML files with import:. Use movelooper edit to open the merged config in the interactive TUI editor.
Self-update
Stay on the latest release with movelooper self-update.
Installation
# 1. Download the binary for your platform from the releases page # https://github.com/lucasassuncao/movelooper/releases # 2. Extract and add to your PATH, then create a config: movelooper edit -o movelooper.yaml
git clone https://github.com/lucasassuncao/movelooper.git cd movelooper go build -o movelooper . ./movelooper edit -o movelooper.yaml
Quick start
Scaffold a config from a template in the TUI editor, then run.
movelooper edit -o movelooper.yaml # create a config from a template in the TUI movelooper --dry-run # preview what would be moved movelooper # move files movelooper watch # real-time monitoring
Examples
configuration: logging: output: both level: info watch: delay: 5m categories: - name: "images" source: path: "C:\\Users\\you\\Downloads" extensions: [jpg, jpeg, png, gif, webp] filter: not: - match: glob: "screenshot_*" age: min: 10m destination: path: "C:\\Users\\you\\Images" conflict-strategy: rename organize-by: "{ext}"
configuration: logging: output: both level: info categories: - name: "photos-backup" source: path: "C:\\Users\\you\\Downloads" extensions: [jpg, jpeg, raw] destination: path: "C:\\Users\\you\\Backup\\photos" action: copy # keep original in Downloads rename: "{mod-date}_{name}.{ext}" # photo.jpg → 2025-04-16_photo.jpg conflict-strategy: skip
configuration: logging: output: both level: info categories: - name: "everything-else" source: path: "C:\\Users\\you\\Downloads" extensions: [all] # matches any file type destination: path: "C:\\Users\\you\\Sorted" conflict-strategy: hash_check organize-by: "{ext}"
movelooper.yaml — main file
configuration: logging: output: console level: info import: - categories/media.yaml - categories/documents.yaml - categories/wallhaven.yaml
categories/wallhaven.yaml — imported file
categories: - name: "wallhaven" source: path: "C:\\Users\\you\\Downloads" extensions: [jpg, png] filter: match: regex: "^wallhaven" destination: path: "C:\\Users\\you\\Walls\\Wallhaven" conflict-strategy: hash_check
Commands
| Command | Description |
|---|---|
| movelooper | Run the move operation once across all categories |
| movelooper watch | Monitor source directories and move files in real-time |
| movelooper undo | Open interactive picker to select and revert a batch |
| movelooper undo --list | List all recorded batches |
| movelooper undo --dry-run | Preview what would be restored |
| movelooper edit | Open the config in an interactive TUI editor |
| movelooper edit -o movelooper.yaml | Scaffold a new config from a template in the TUI editor |
| movelooper validate | Validate a config file and report all errors |
| movelooper config | Print the resolved configuration file path |
| movelooper show-docs | Browse the field reference in the terminal |
| movelooper self-update | Download and install the latest release |