clipvault

Crates.ioclipvault
lib.rsclipvault
version1.0.0
created_at2025-08-29 16:06:25.422607+00
updated_at2025-08-29 16:06:25.422607+00
descriptionClipboard history manager for Wayland, inspired by cliphist
homepagehttps://github.com/rolv-apneseth/clipvault
repositoryhttps://github.com/rolv-apneseth/clipvault
max_upload_size
id1816069
size112,501
Rolv Apneseth (Rolv-Apneseth)

documentation

README

Clipvault

Clipboard history manager for Wayland, inspired by cliphist

License: AGPL v3 version Crates.io Version AUR version

https://github.com/user-attachments/assets/4ede611c-befd-4535-b321-af12f054dae4

Features

Like cliphist:

  • Save history: clipboard entries are stored in a local database
  • Recall history: recall saved entries using any picker you like (e.g. dmenu, rofi, wofi, etc.)
  • Simple: no builtin picker, only pipes - keep it simple (stupid)
  • Any data: support for text, images and any other binary data
  • Preservation: entries are preserved byte-for-byte, including leading/trailing whitespace

In addition:

  • No silent failures: invalid arguments cause errors, and are also written to log files
  • Relative positions: support for getting/deleting items by relative position in the saved history
  • Entry size limits: configurable minimum and maximum size for stored entries
  • Entry age limit: configurable max age for entries - automatically remove old clipboard entries

Requirements

  • wl-clipboard, or anything with an interface equivalent to wl-clipboard --watch to keep clipvault updated with the latest clipboard entries.

Installation

Cargo

cargo install clipvault --locked

Or, directly from source:

cargo install --git https://github.com/rolv-apneseth/clipvault --locked

AUR

paru -S clipvault

Setup

wl-paste --watch clipvault store

This will listen for changes from the Wayland clipboard and write each entry to the history. Call it once per session - for example:

  • Hyprland:

    exec-once = wl-paste --watch clipvault store
    
  • Sway:

    exec wl-paste --watch clipvault store
    

Filtering

If you wish to narrow down the MIME types copied to clipvault, you can run wl-paste --watch once for each type that should actually get forwarded to clipvault:

wl-paste --type text --watch clipvault store # Forward text data
wl-paste --type image --watch clipvault store # Forward raw image data

[!TIP] Use wl-paste --list-types to find the available MIME types for the currently copied data in the Wayland clipboard.

Image data from browsers

When copying images from browsers, wl-paste will usually pass the data to clipvault as text/html. This is not ideal for copying images, and you may wish to have the raw image data copied instead. If so, you can either only forward image data, or, more realistically, use the below and filter out entries which start with <meta http-equiv= in your picker (check out some of the scripts in extras - I personally use the rofi script):

wl-paste --watch clipvault store # Forward all data 
wl-paste --type image --watch clipvault store # Forward specifically raw image data 

Usage

Select an entry (picker)

clipvault list | dmenu | clipvault get | wl-copy

I recommend making a keybind for this one with your favourite picker (see picker examples below).

Select an entry (relative index)

clipvault get --index 0 # Newest entry
clipvault get --index 1 # Entry just before the newest entry 
clipvault get --index -1 # Oldest entry

Delete an entry (picker)

clipvault list | dmenu | clipvault delete

The rofi script in extras, which creates a custom mode, uses clipvault delete to remove entries directly from within the rofi window.

Delete an entry (relative index)

clipvault delete --index 0 # Delete the newest entry
clipvault delete --index 1 # Delete the entry just before the newest entry
clipvault delete --index -1 # Delete the oldest entry

Delete all entries

cliphist clear

Alternatively, just delete the database file (default path can be found in help output).

Additional information

  • Logs are written to $XDG_STATE_HOME/clipvault/logs
  • Log level can be changed using the RUST_LOG env var, e.g. RUST_LOG="trace"
  • ANSI colours used for errors printed to STDOUT can be disabled with NO_COLOR=1

Picker Examples

Examples of basic setups for different picker programs, such as rofi and dmenu.

Many of the below examples will show only the second column of the output from clipvault list (each line is separated by \t). Like cliphist, it's important that a line prefixed with a number is piped into clipvault get. This number is used to look up in the database the exact original selection that was made, with all leading/trailing/non-printable whitespace preserved, none of which is shown in the preview output of clipvault list.

dmenu
clipvault list | dmenu | clipvault get | wl-copy
fzf
clipvault list | fzf --no-sort -d $'\t' --with-nth 2 | clipvault get | wl-copy
rofi
clipvault list | rofi -dmenu -display-columns 2 | clipvault get | wl-copy
fuzzel
clipvault list | fuzzel --dmenu --with-nth 2 | clipvault get | wl-copy
wofi
clipvault list | wofi -S dmenu --pre-display-cmd "echo '%s' | cut -f 2" | clipvault get | wl-copy

Note also that by default wofi may sort entries alphabetically or by its cache. To display entries in the order they are produced, try adding the following arguments to the wofi call above:

-d -k /dev/null
tofi
clipvault list | tofi | clipvault get | wl-copy

For more advanced setups, checkout some of the scripts in the extras directory. Contributions are welcome.

[!TIP] To avoid proceeding with copying if no entry was selected in the picker, try replacing clipvault get | wl-copy from any of the above commands with { read -r output && clipvault get <<< "$output" | wl-copy }

Configuration

While there is no support for a dedicated configuration file, clipvault does support loading additional CLI arguments from files, thanks to argfile.

To use this functionality, create a file with one argument per line, like this example.

Then, provide its path to the CLI using:

clipvault @/path/to/argfile

[!TIP] Most options can also be set using environment variables - check out the help output for each command to find the specific variable to set for each.

Contributing

All contributions are welcome. If you run into any problems, or have any suggestions/feedback, feel free to open an issue.

This project is written in Rust, so for contributing code:

  1. Ensure rustup is installed - this project uses the stable toolchain for most things, but nightly for the formatting.

  2. Make your changes and ensure they work as expected - cargo run -- your_args_here.

  3. Lint + format + run tests:

    cargo clippy --all -- -W clippy::all && cargo +nightly fmt && cargo test
    
  4. LGTM 👍

I like just, so I keep some utility commands in the justfile. Check that out for additional checks which are run in the CI.

Similar programs

Acknowledgements

License

This code is licensed under the AGPLv3.

See the LICENSE file for more details.

Commit count: 13

cargo fmt