Skip to main content

Power-user macOS clipboard manager with menu bar, global hotkeys, and search

Project description

clipmon (clippal)

PyPI Python License: MIT CI

A power-user macOS clipboard manager. Monitors your clipboard, stores history in SQLite with full-text search, and provides a menu bar app with a floating overlay and keyboard-driven search panel. The goal: a clipboard manager so useful it becomes an extension of your keyboard.

Quick start

brew install clippal          # or: pip install clippal
clippal ui                    # starts in background, look for 📋 in menu bar

macOS will ask for Accessibility permission on first launch — grant it for global hotkeys to work. Then:

  • Ctrl+Opt+F — open search panel (browse, search, edit, create clips)
  • Ctrl+Opt+V — peek at clipboard (hold to browse history)

Features

  • Clipboard monitoring -- polls NSPasteboard.changeCount at 500ms, stores text with metadata (source app, content type, timestamps)
  • Duplicate handling -- same text bumps copy count + moves to top instead of creating a new entry
  • Smart filtering -- skips password managers (ConcealedType), transient content, auto-generated clipboard writes
  • Full-text search -- FTS5-powered search across all clipboard history
  • Menu bar app -- browse recent clips, click to copy back, pin/unpin items
  • Search panel -- floating split-pane with live typeahead, history (left) + favourites (right), inline editing, right-click context menu, hover preview, and scrollable help
  • Floating overlay -- hold-to-peek panel showing current clipboard content with history cycling
  • Global hotkeys -- configurable shortcuts (Ctrl+Option+V for overlay, Ctrl+Option+F for search). Requires Accessibility permission
  • Singleton process -- only one instance runs at a time, clipmon stop to shut down
  • File logging -- logs to ~/.config/clipmon/clipmon.log, view with clipmon logs
  • CLI tools -- list, search, stats, export (JSON/CSV), clear, stop, logs

Requirements

  • macOS (tested on macOS 26 Tahoe)
  • Python >= 3.9
  • Accessibility permission (for global hotkeys)

Installation

From PyPI (recommended)

pip install clippal

From Homebrew

brew tap naxatar/tap
brew install clippal

From source (development)

git clone https://github.com/naxatar/clippal.git && cd clippal
python3 -m venv venv && source venv/bin/activate
pip install -e ".[dev]"

Post-install

clipmon requires Accessibility permission for global hotkeys (Ctrl+Opt+V overlay, Ctrl+Opt+F search). macOS will prompt on first launch, or grant manually in System Settings > Privacy & Security > Accessibility.

Usage

Menu bar app (recommended)

clipmon ui

Launches the menu bar app in the background and exits immediately. If already running, shows status with PID, uptime, and clip stats:

clipmon: running (pid 12345, uptime 2h 15m)
  Clips: 142  Pinned: 5  Apps: 12

Features:

  • Dropdown showing recent clips (click to copy back)
  • Pinned clips section
  • Search (Ctrl+Option+F)
  • Floating overlay toggle (Ctrl+Option+V)
  • Copy count badges on frequently copied items

Managing the process

clipmon ui                      # Start (background) or show status
clipmon stop                    # Stop the running instance
clipmon logs                    # Show last 50 log lines
clipmon logs -f                 # Follow logs live (tail -f)
clipmon logs -n 100             # Show last 100 lines

Uninstalling

clipmon uninstall               # Stops clipmon, removes all data (~/.config/clipmon/)
pip uninstall clippal           # or: brew uninstall clippal

This removes your clipboard history database, config file, and logs. Use clipmon uninstall -y to skip the confirmation prompt.

CLI commands

clipmon list                    # Show recent clipboard history
clipmon list --limit 50 -v      # 50 items, verbose (timestamps, source app)
clipmon search "query"          # Full-text search
clipmon stats                   # Total clips, top copied, top apps
clipmon export                  # JSON to stdout
clipmon export --format csv     # CSV to stdout
clipmon clear                   # Clear history (with confirmation)
clipmon clear -y                # Clear without confirmation

Search panel

Open with Ctrl+Option+F. A floating split-pane with History (left, 60%) and Favourites (right, 40%).

Navigation

Key Action
/ Move through list (down enters table, up from row 0 returns to search)
← → Switch between History and Favourites
Enter Copy selected clip to clipboard
Cmd+Enter Paste directly into the active app (simulates Cmd+V)
Esc Close panel / cancel edit
? Toggle scrollable help overlay

Actions (select a clip first)

Key Action
E Edit clip in preview area
F Toggle favourite (pin/unpin)
O Open -- URL opens in browser, short text opens as Google search
D Delete clip

Edit mode

The preview area at the bottom is always editable. Click it or press E to start editing. Changes are auto-detected.

Key Action
Cmd+S Save edit (overwrite original)
Cmd+Shift+S Save as new clip (keep original)
Esc Cancel and revert

Navigation is blocked while editing to prevent accidental data loss.

Mouse interactions

Action Effect
Hover Highlights row and shows preview (reverts on mouse leave)
Click Selects row
Double-click Pastes clip and closes panel
Cmd+click Opens clip (same as O key)
Right-click Context menu (Paste, Edit, Favourite, Open, Delete)
Click ⋯ Same context menu via three-dot button on each row

Keyboard always takes priority over mouse hover -- pressing any arrow key clears the hover state and resumes from the keyboard's last position.

Overlay

Toggle with Ctrl+Option+V. A translucent hold-to-peek panel showing clipboard content.

Key Action
Ctrl+Opt+V Show overlay / cycle back through history
Shift+Ctrl+Opt+V Cycle forward (rewind) through history
Release Ctrl Close overlay

Configuration

Config file: ~/.config/clipmon/config.yml (auto-created on first run)

Setting Default Description
polling_interval 0.5 Clipboard poll frequency (seconds)
max_history 1000 Maximum clips to keep
db_path ~/.config/clipmon/clipmon.db SQLite database location
skip_concealed true Skip password manager entries
skip_transient true Skip transient clipboard items
log_level INFO Logging level
hotkey_toggle_overlay ctrl+alt+v Overlay toggle shortcut
hotkey_open_search ctrl+alt+f Search shortcut
overlay_x / overlay_y 100 Overlay panel position (saved automatically)
overlay_visible false Restore overlay on launch
suggestion_threshold 5 Copies before suggesting a shortcut

Architecture

src/clipmon/
  cli.py            CLI entry point (argparse)
  config.py         YAML config with defaults
  db.py             SQLite + FTS5 storage layer
  watcher.py        Clipboard polling (daemon thread)
  menubar.py        Menu bar app + clipboard integration (pure PyObjC)
  overlay.py        Floating NSPanel overlay
  search_window.py  Search panel with split tables, inline editing, context menus
  hotkeys.py        Global keyboard shortcuts (NSEvent monitors)
  pidfile.py        Singleton process management

Storage

  • SQLite with WAL mode for concurrent read/write
  • SHA-256 dedup -- O(1) duplicate detection via content hash index
  • FTS5 virtual table synced via triggers for instant full-text search
  • Schema: clips table with id, content_text, content_hash, content_type, source_app, created_at, updated_at, copy_count, pinned

UI

  • Menu bar via pure PyObjC (NSStatusItem + NSMenu) -- runs on main NSRunLoop, no thread-safety issues
  • Overlay via PyObjC NSPanel -- borderless, non-activating, vibrancy HUD material, hold-to-peek with history cycling
  • Search panel via PyObjC NSPanel -- floating split-pane with live typeahead, inline preview editing, right-click context menu with ⋯ button, hover highlight, double-click paste, Cmd+click open
  • Hotkeys via NSEvent global/local monitors -- requires Accessibility permission

Tests

pytest          # 305 tests, ~2.5s
pytest -v       # verbose output

All PyObjC code is tested via fake AppKit classes (FakePanel, FakeNSEvent, FakeTableView, etc.) with module reload + namespace patching. No real NSApplication needed.

Project status

Milestone Status
1. Core Clipboard Monitor Complete
2. Menu Bar App + Floating UI Complete
3. Smart Clipboard (search panel, inline editing, keyboard-driven paste) Complete

See docs/MILESTONES.md for details, docs/ARCHITECTURE.md for system overview, and docs/VISION.md for where this is headed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clippal-0.1.0.tar.gz (63.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clippal-0.1.0-py3-none-any.whl (42.3 kB view details)

Uploaded Python 3

File details

Details for the file clippal-0.1.0.tar.gz.

File metadata

  • Download URL: clippal-0.1.0.tar.gz
  • Upload date:
  • Size: 63.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for clippal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 22f7f1d8e5b936d31d79340a483b5f825537df6fbcf89ddc3ce844af326661bc
MD5 4b85fac7ec9d981b6b9b6de0d6bad1e4
BLAKE2b-256 86ae27854bd5bcdec9c4934f0bb5a10ce194b8e3af974905348ede4f44b8af6e

See more details on using hashes here.

File details

Details for the file clippal-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: clippal-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 42.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for clippal-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bd52c22a9358ab245e7d978a1aad3a7128c0487f5b1b1b8b700840f20dcab5ce
MD5 a760e77521acd2b76b1f7a1d43116625
BLAKE2b-256 1bf2c459fc78786fb92dcca8b6118832354f7f85a8d1f930ee8a231faa05e3a4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page