movelooper logo

A modern CLI tool that automatically organizes and moves your files based on configurable categories. No manual sorting, no chaos.

⬇ Download latest ★ View on GitHub

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
movelooperRun the move operation once across all categories
movelooper watchMonitor source directories and move files in real-time
movelooper undoOpen interactive picker to select and revert a batch
movelooper undo --listList all recorded batches
movelooper undo --dry-runPreview what would be restored
movelooper editOpen the config in an interactive TUI editor
movelooper edit -o movelooper.yamlScaffold a new config from a template in the TUI editor
movelooper validateValidate a config file and report all errors
movelooper configPrint the resolved configuration file path
movelooper show-docsBrowse the field reference in the terminal
movelooper self-updateDownload and install the latest release