Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cliphist for openSUSE:Factory checked in at 2025-10-31 16:27:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cliphist (Old) and /work/SRC/openSUSE:Factory/.cliphist.new.1980 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cliphist" Fri Oct 31 16:27:59 2025 rev:2 rq:1314588 version:0.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/cliphist/cliphist.changes 2025-01-19 21:49:27.814635910 +0100 +++ /work/SRC/openSUSE:Factory/.cliphist.new.1980/cliphist.changes 2025-10-31 16:28:34.607207335 +0100 @@ -1,0 +2,17 @@ +Thu Oct 30 17:38:42 UTC 2025 - Lorenz Holzbauer <[email protected]> + +- Update to version 0.7.0 + * Added min-store-length option + * Compact database after wiping + * Added contrib scripts and improvements: + - fuzzel img script + - option to delete specific entry in cliphist-fuzzel-img + - systemd service + - cliphist-wofi-img: disable cache + - drop ImageMagick in cliphist-fuzzel-img + - use portable shebang lines + * Added support for TIFF images + * Fixed error when ID not found during decode + * Fixed min-store-length setting max length instead of min + +------------------------------------------------------------------- Old: ---- cliphist-v0.6.1.tar.gz New: ---- cliphist-v0.7.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cliphist.spec ++++++ --- /var/tmp/diff_new_pack.5E9PYz/_old 2025-10-31 16:28:35.383240308 +0100 +++ /var/tmp/diff_new_pack.5E9PYz/_new 2025-10-31 16:28:35.387240477 +0100 @@ -1,7 +1,7 @@ # # spec file for package cliphist # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # Copyright (c) 2025 Lorenz Holzbauer # # All modifications and additions to the file contributed by third parties @@ -18,7 +18,7 @@ Name: cliphist -Version: 0.6.1 +Version: 0.7.0 Release: 0 Summary: A wayland clipboard manager with support for multimedia License: GPL-3.0-only ++++++ cliphist-v0.6.1.tar.gz -> cliphist-v0.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/CHANGELOG.md new/cliphist-0.7.0/CHANGELOG.md --- old/cliphist-0.6.1/CHANGELOG.md 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/CHANGELOG.md 2025-10-11 15:22:56.000000000 +0200 @@ -1,5 +1,27 @@ # Changelog +## [0.7.0](https://www.github.com/sentriz/cliphist/compare/v0.6.1...v0.7.0) (2025-10-11) + +A small release, mostly featuring the `min-store-length` option. + +### Features + +* add `min-store-length` option ([e18c06a](https://www.github.com/sentriz/cliphist/commit/e18c06a316a4c25741d2b3e721c7b4a9ff85390c)), closes [#62](https://www.github.com/sentriz/cliphist/issues/62) [#157](https://www.github.com/sentriz/cliphist/issues/157) +* compact db after wiping ([9fb195b](https://www.github.com/sentriz/cliphist/commit/9fb195b66d8dfd5950416efdd47f7a62a8d32cd0)), closes [#155](https://www.github.com/sentriz/cliphist/issues/155) +* **contrib:** add fuzzel img script ([#144](https://www.github.com/sentriz/cliphist/issues/144)) ([9dac7d3](https://www.github.com/sentriz/cliphist/commit/9dac7d3ff533140ad31e835a413a8380b99f96d3)) +* **contrib:** add option to delete specific entry in cliphist-fuzzel-img ([#148](https://www.github.com/sentriz/cliphist/issues/148)) ([ff1d247](https://www.github.com/sentriz/cliphist/commit/ff1d247e3521bd7ebcb6463f86349bab71440496)) +* **contrib:** add systemd service ([#138](https://www.github.com/sentriz/cliphist/issues/138)) ([e626b1b](https://www.github.com/sentriz/cliphist/commit/e626b1b60083453b4ff74f7c8dc251415e2abbc4)) +* **contrib:** cliphist-wofi-img: disable cache ([#156](https://www.github.com/sentriz/cliphist/issues/156)) ([5c33a7d](https://www.github.com/sentriz/cliphist/commit/5c33a7d8d4bb7bf44fe0526d7451edca2157ab75)) +* **contrib:** drop imagemagick in cliphist-fuzzel-img ([#153](https://www.github.com/sentriz/cliphist/issues/153)) ([6eda526](https://www.github.com/sentriz/cliphist/commit/6eda526d02119ebc09ec0f64b0a96ed4540f5a83)) +* **contrib:** use portable shebang lines ([#147](https://www.github.com/sentriz/cliphist/issues/147)) ([f49bd90](https://www.github.com/sentriz/cliphist/commit/f49bd905cff72d32d62c209224353865436f9a13)) +* support tiff images ([1350191](https://www.github.com/sentriz/cliphist/commit/1350191061a7df1f70cd6e652eb0517d3a9a590f)), closes [#126](https://www.github.com/sentriz/cliphist/issues/126) + + +### Bug Fixes + +* error when id not during decode ([b35d005](https://www.github.com/sentriz/cliphist/commit/b35d00590a9fccc4285d562938c5428c9eaa6a37)), closes [#159](https://www.github.com/sentriz/cliphist/issues/159) +* min-store-length sets max length instead of min ([#163](https://www.github.com/sentriz/cliphist/issues/163)) ([a94f192](https://www.github.com/sentriz/cliphist/commit/a94f192d94e43eee2d58fff6fb3733702eadb854)) + ### [0.6.1](https://www.github.com/sentriz/cliphist/compare/v0.6.0...v0.6.1) (2024-10-15) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/cliphist.go new/cliphist-0.7.0/cliphist.go --- old/cliphist-0.6.1/cliphist.go 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/cliphist.go 2025-10-11 15:22:56.000000000 +0200 @@ -20,10 +20,12 @@ _ "image/jpeg" _ "image/png" - "go.senan.xyz/flagconf" _ "golang.org/x/image/bmp" + _ "golang.org/x/image/tiff" + "github.com/rivo/uniseg" bolt "go.etcd.io/bbolt" + "go.senan.xyz/flagconf" ) //go:embed version.txt @@ -54,6 +56,7 @@ maxItems := flag.Uint64("max-items", 750, "maximum number of items to store") maxDedupeSearch := flag.Uint64("max-dedupe-search", 100, "maximum number of last items to look through when finding duplicates") + minLength := flag.Uint("min-store-length", 0, "minimum number of characters to store") previewWidth := flag.Uint("preview-width", 100, "maximum number of characters to preview") dbPath := flag.String("db-path", filepath.Join(cacheHome, "cliphist", "db"), "path to db") configPath := flag.String("config-path", filepath.Join(configHome, "cliphist", "config"), "overwrite config path to use instead of cli flags") @@ -69,7 +72,7 @@ case "clear": err = deleteLast(*dbPath) default: - err = store(*dbPath, os.Stdin, *maxDedupeSearch, *maxItems) + err = store(*dbPath, os.Stdin, *maxDedupeSearch, *maxItems, *minLength) } case "list": err = list(*dbPath, os.Stdout, *previewWidth) @@ -80,7 +83,7 @@ case "delete": err = delete(*dbPath, os.Stdin) case "wipe": - err = wipe(*dbPath) + err = wipeAndCompact(*dbPath) case "version": fmt.Fprintf(flag.CommandLine.Output(), "%s\t%s\n", "version", strings.TrimSpace(version)) flag.VisitAll(func(f *flag.Flag) { @@ -96,7 +99,7 @@ } } -func store(dbPath string, in io.Reader, maxDedupeSearch, maxItems uint64) error { +func store(dbPath string, in io.Reader, maxDedupeSearch, maxItems uint64, minLength uint) error { input, err := io.ReadAll(in) if err != nil { return fmt.Errorf("read stdin: %w", err) @@ -104,6 +107,9 @@ if len(input) > 5*1e6 { // don't store >5MB return nil } + if int(minLength) > 0 && graphemeClusterCount(string(input)) < int(minLength) { + return nil + } db, err := initDB(dbPath) if err != nil { @@ -242,6 +248,10 @@ b := tx.Bucket([]byte(bucketKey)) v := b.Get(itob(id)) + if v == nil { + return fmt.Errorf("id %d not found", id) + } + if _, err := out.Write(v); err != nil { return fmt.Errorf("writing out: %w", err) } @@ -337,6 +347,16 @@ return nil } +func wipeAndCompact(dbPath string) error { + if err := wipe(dbPath); err != nil { + return fmt.Errorf("wipe: %w", err) + } + if err := compactDB(dbPath); err != nil { + return fmt.Errorf("compact: %w", err) + } + return nil +} + func wipe(dbPath string) error { db, err := initDB(dbPath) if err != nil { @@ -399,6 +419,43 @@ return db, nil } +func compactDB(path string) error { + srcDB, err := bolt.Open(path, 0644, &bolt.Options{ + ReadOnly: true, + Timeout: 1 * time.Second, + }) + if err != nil { + return fmt.Errorf("open source db: %w", err) + } + defer srcDB.Close() + + tmpPath := path + ".tmp" + dstDB, err := bolt.Open(tmpPath, 0644, &bolt.Options{ + Timeout: 1 * time.Second, + }) + if err != nil { + return fmt.Errorf("open destination db: %w", err) + } + defer dstDB.Close() + + if err := bolt.Compact(dstDB, srcDB, 0); err != nil { + os.Remove(tmpPath) + return fmt.Errorf("compact db: %w", err) + } + + if err := srcDB.Close(); err != nil { + return fmt.Errorf("close source db: %w", err) + } + if err := dstDB.Close(); err != nil { + return fmt.Errorf("close destination db: %w", err) + } + + if err := os.Rename(tmpPath, path); err != nil { + return fmt.Errorf("replace db: %w", err) + } + return nil +} + func preview(index uint64, data []byte, width uint) string { if config, format, err := image.DecodeConfig(bytes.NewReader(data)); err == nil { return fmt.Sprintf("%d%s[[ binary data %s %s %dx%d ]]", @@ -419,6 +476,10 @@ return in } +func graphemeClusterCount(str string) int { + return uniseg.GraphemeClusterCount(str) +} + func min(a, b int) int { //nolint:unused // we still support go1.19 if a < b { return a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/cliphist_test.go new/cliphist-0.7.0/cliphist_test.go --- old/cliphist-0.6.1/cliphist_test.go 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/cliphist_test.go 2025-10-11 15:22:56.000000000 +0200 @@ -15,6 +15,7 @@ "github.com/rogpeppe/go-internal/testscript" "golang.org/x/image/bmp" + "golang.org/x/image/tiff" ) func TestMain(m *testing.M) { @@ -39,10 +40,11 @@ return 0 }, - "gif": func() int { _ = gif.Encode(os.Stdout, testImage, nil); return 0 }, - "jpg": func() int { _ = jpeg.Encode(os.Stdout, testImage, nil); return 0 }, - "png": func() int { _ = png.Encode(os.Stdout, testImage); return 0 }, - "bmp": func() int { _ = bmp.Encode(os.Stdout, testImage); return 0 }, + "gif": func() int { _ = gif.Encode(os.Stdout, testImage, nil); return 0 }, + "jpg": func() int { _ = jpeg.Encode(os.Stdout, testImage, nil); return 0 }, + "png": func() int { _ = png.Encode(os.Stdout, testImage); return 0 }, + "bmp": func() int { _ = bmp.Encode(os.Stdout, testImage); return 0 }, + "tiff": func() int { _ = tiff.Encode(os.Stdout, testImage, nil); return 0 }, })) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/contrib/cliphist-fuzzel-img new/cliphist-0.7.0/contrib/cliphist-fuzzel-img --- old/cliphist-0.6.1/contrib/cliphist-fuzzel-img 1970-01-01 01:00:00.000000000 +0100 +++ new/cliphist-0.7.0/contrib/cliphist-fuzzel-img 2025-10-11 15:22:56.000000000 +0200 @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +thumbnail_dir="${XDG_CACHE_HOME:-$HOME/.cache}/cliphist/thumbnails" + +cliphist_list=$(cliphist list) +if [ -z "$cliphist_list" ]; then + fuzzel -d --prompt-only "cliphist: please store something first " + rm -rf "$thumbnail_dir" + exit +fi + +[ -d "$thumbnail_dir" ] || mkdir -p "$thumbnail_dir" + +# Write binary image to cache file if it doesn't exist +read -r -d '' thumbnail <<EOF +/^[0-9]+\s<meta http-equiv=/ { next } +match(\$0, /^([0-9]+)\s(\[\[\s)?binary.*(jpg|jpeg|png|bmp)/, grp) { + cliphist_item_id=grp[1] + ext=grp[3] + thumbnail_file=cliphist_item_id"."ext + system("[ -f ${thumbnail_dir}/"thumbnail_file" ] || echo " cliphist_item_id "\\\\\t | cliphist decode >${thumbnail_dir}/"thumbnail_file) + print \$0"\0icon\x1f${thumbnail_dir}/"thumbnail_file + next +} +1 +EOF + +item=$(echo "$cliphist_list" | gawk "$thumbnail" | fuzzel -d --placeholder "Search clipboard..." --counter --no-sort --with-nth 2) +exit_code=$? + +# ALT+0 to clear history +if [ "$exit_code" -eq 19 ]; then + confirmation=$(echo -e "No\nYes" | fuzzel -d --placeholder "Delete history?" --lines 2) + [ "$confirmation" == "Yes" ] && rm ~/.cache/cliphist/db && rm -rf "$thumbnail_dir" +# ALT+1 to delete selected item +# configure the keybind with `custom-1` in your fuzzel.ini +elif [ "$exit_code" -eq 10 ]; then + if [ -n "$item" ]; then + item_id=$(echo "$item" | cut -f1) + echo "$item_id" | cliphist delete + find "$thumbnail_dir" -name "${item_id}.*" -delete + fi +else + [ -z "$item" ] || echo "$item" | cliphist decode | wl-copy +fi + +# Delete cached thumbnails that are no longer in cliphist db +find "$thumbnail_dir" -type f | while IFS= read -r thumbnail_file; do + cliphist_item_id=$(basename "${thumbnail_file%.*}") + if ! grep -q "^${cliphist_item_id}\s\[\[ binary data" <<<"$cliphist_list"; then + rm "$thumbnail_file" + fi +done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/contrib/cliphist-wofi-img new/cliphist-0.7.0/contrib/cliphist-wofi-img --- old/cliphist-0.6.1/contrib/cliphist-wofi-img 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/contrib/cliphist-wofi-img 2025-10-11 15:22:56.000000000 +0200 @@ -1,4 +1,4 @@ -#!/usr/bin/bash +#!/usr/bin/env bash # executes same behaviour as below but with support for images # @@ -37,7 +37,7 @@ 1 EOF -choice=$(gawk <<< $cliphist_list "$prog" | wofi -I --dmenu -Dimage_size=100 -Dynamic_lines=true) +choice=$(gawk <<< $cliphist_list "$prog" | wofi -I --dmenu --cache-file=/dev/null -Dimage_size=100 -Dynamic_lines=true) # stop execution if nothing selected in wofi menu [ -z "$choice" ] && exit 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/contrib/cliphist.service new/cliphist-0.7.0/contrib/cliphist.service --- old/cliphist-0.6.1/contrib/cliphist.service 1970-01-01 01:00:00.000000000 +0100 +++ new/cliphist-0.7.0/contrib/cliphist.service 2025-10-11 15:22:56.000000000 +0200 @@ -0,0 +1,15 @@ +[Unit] +Description=Wayland clipboard manager with support for multimedia +PartOf=graphical-session.target +After=graphical-session.target +Requisite=graphical-session.target + +[Service] +Type=simple +ExecStart=/usr/bin/wl-paste --watch cliphist store +Restart=on-failure + +[Install] +WantedBy=graphical-session.target + +# vim:ft=dosini diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/go.mod new/cliphist-0.7.0/go.mod --- old/cliphist-0.6.1/go.mod 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/go.mod 2025-10-11 15:22:56.000000000 +0200 @@ -3,6 +3,7 @@ go 1.20 require ( + github.com/rivo/uniseg v0.4.7 github.com/rogpeppe/go-internal v1.12.0 go.etcd.io/bbolt v1.3.9 go.senan.xyz/flagconf v0.1.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/go.sum new/cliphist-0.7.0/go.sum --- old/cliphist-0.6.1/go.sum 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/go.sum 2025-10-11 15:22:56.000000000 +0200 @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/readme.md new/cliphist-0.7.0/readme.md --- old/cliphist-0.6.1/readme.md 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/readme.md 2025-10-11 15:22:56.000000000 +0200 @@ -1,57 +1,53 @@ ### cliphist -_clipboard history “manager” for wayland_ +_Clipboard history “manager” for Wayland_ -- write clipboard changes to a history file -- recall history with **dmenu** / **rofi** / **wofi** (or whatever other picker you like) -- both **text** and **images** are supported -- clipboard is preserved **byte-for-byte** - - leading / trailing whitespace / no whitespace or newlines are - preserved - - won’t break fancy editor selections like vim wordwise, linewise, - block mode -- no concept of a picker, only pipes +- Write clipboard changes to a history file. +- Recall history with **dmenu**, **rofi**, **wofi** (or whatever other picker you like). +- Both **text** and **images** are supported. +- Clipboard is preserved **byte-for-byte**. + - Leading/trailing whitespace, no whitespace, or newlines are preserved. + - Won’t break fancy editor selections like Vim wordwise, linewise, or block mode. +- No concept of a picker, only pipes. -requires: [go](https://golang.org/), -[wl-clipboard](https://github.com/bugaevc/wl-clipboard), xdg-utils (for -image mime inferance) +Requires [Go](https://golang.org/), [wl-clipboard](https://github.com/bugaevc/wl-clipboard), xdg-utils (for image MIME inference). --- -### install +### Install -- you could try using [your distro's repos](#packaging) if it's available there -- or stick a static binary from the [releases page](https://github.com/sentriz/cliphist/releases) somewhere in your `$PATH` -- or just install it from source with [go](https://go.dev/doc/install) and `$ go install go.senan.xyz/cliphist@latest` +- You could try using [your distro's repos](#packaging) if it's available there. +- Or stick a static binary from the [releases page](https://github.com/sentriz/cliphist/releases) somewhere in your `$PATH`. +- Or just install it from source with [Go](https://go.dev/doc/install) and `$ go install go.senan.xyz/cliphist@latest`. --- -### usage +### Usage -#### listen for clipboard changes +#### Listen for clipboard changes `$ wl-paste --watch cliphist store` -this will listen for changes on your primary clipboard and write them to the history. -call it once per session - for example in your sway config +This will listen for changes on your primary clipboard and write them to the history. +Call it once per session - for example, in your Sway config. -#### select old item +#### Select an old item `$ cliphist list | dmenu | cliphist decode | wl-copy` -bind it to something nice on your keyboard +Bind it to something nice on your keyboard. -#### delete old item +#### Delete an old item `$ cliphist list | dmenu | cliphist delete` -or else query manually -`$ cliphist delete-query "secret item"` +Or else query manually: +`$ cliphist delete-query "secret item"`. -#### clear database +#### Clear database -`$ cliphist wipe` +`$ cliphist wipe`. --- -### picker examples +### Picker examples <details> <summary>dmenu</summary> @@ -75,11 +71,27 @@ </details> <details> +<summary>fuzzel (dmenu mode)</summary> + +`cliphist list | fuzzel --dmenu | cliphist decode | wl-copy` + +</details> + +<details> +<summary>fuzzel (dmenu mode with images)</summary> + +`./cliphist-fuzzel-img` + +(Requires [contrib/cliphist-fuzzel-img](./contrib/cliphist-fuzzel-img)) + +</details> + +<details> <summary>rofi (custom mode)</summary> `rofi -modi clipboard:/path/to/cliphist-rofi -show clipboard` -(requires [contrib/cliphist-rofi](https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-rofi)) +(Requires [contrib/cliphist-rofi](https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-rofi)). </details> @@ -88,32 +100,34 @@ `rofi -modi clipboard:/path/to/cliphist-rofi-img -show clipboard -show-icons` -(requires [contrib/cliphist-rofi-img](https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-rofi-img)) +(Requires [contrib/cliphist-rofi-img](https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-rofi-img)). </details> <details> - <summary>wofi</summary> +<summary>wofi</summary> - `cliphist list | wofi -S dmenu | cliphist decode | wl-copy` +`cliphist list | wofi -S dmenu | cliphist decode | wl-copy` + +Example config for Sway: - Example config for sway: ``` exec wl-paste --watch cliphist store bindsym Mod1+p exec cliphist list | wofi -S dmenu | cliphist decode | wl-copy ``` + </details> --- -### faq +### FAQ <details> -<summary><strong>why do i have numbers in my picker? can i get rid of them?</strong></summary> +<summary><strong>Why do I have numbers in my picker? Can I get rid of them?</strong></summary> -it's important that a line prefixed with a number is piped into `cliphist decode`. this number is used to lookup in the database the exact original selection that you made, with all leading, trailing, non printable etc whitespace presevered. none of that will not be shown in the preview output of `cliphist list` +It's important that a line prefixed with a number is piped into `cliphist decode`. This number is used to look up in the database the exact original selection that you made, with all leading, trailing, non-printable, etc. whitespace preserved. None of that will be shown in the preview output of `cliphist list`. -since the format of `cliphist list` is `"<id>\t<100 char preview>"`, and most pickers consider `"\t"` to be column seperator, you can try to just select column number 2 +Since the format of `cliphist list` is `"<id>\t<100 char preview>"`, and most pickers consider `"\t"` to be a column separator, you can try to just select column number 2. ```shell # fzf @@ -126,37 +140,69 @@ ``` ```shell +# fuzzel +cliphist list | fuzzel --dmenu --with-nth 2 | cliphist decode | wl-copy +``` + +```shell # wofi -# it kind of works but breaks with quotes in the original selection. i recommend not trying to hide the column with wofi +# It kind of works but breaks with quotes in the original selection. I recommend not trying to hide the column with wofi. cliphist list | wofi --dmenu --pre-display-cmd "echo '%s' | cut -f 2" | cliphist decode | wl-copy ``` </details> <details> -<summary><strong>how do i narrow down the items that are copied to cliphist, or always copy images from my browser?</strong></summary> +<summary><strong>How do I narrow down the items that are copied to cliphist, or always copy images from my browser?</strong></summary> -it's also possible to run `wl-paste --watch` several times for multiple mime types +It's also possible to run `wl-paste --watch` several times for multiple MIME types. -for example in your window manager's startup you could run +For example, in your window manager's startup, you could run: ``` wl-paste --type text --watch cliphist store wl-paste --type image --watch cliphist store ``` -now you should have text and raw image data available in your history. make sure you have xdg-utils installed too +Now you should have text and raw image data available in your history. Make sure you have xdg-utils installed too. </details> --- -### packaging +### Packaging [](https://repology.org/project/cliphist/versions) --- -### video +### Demo <https://user-images.githubusercontent.com/6832539/230513908-b841fffe-d7d5-46c2-b29f-28b3e91daa74.mp4> + +--- + +### Configuration + +`cliphist` can be optionally configured to extend the default functionality. Any option can be provided with a CLI argument, environment variable, or config file key. + +For example, the option `max-items`, can be set via the CLI as `-max-items 100`, as an environment variable `CLIPHIST_MAX_ITEMS=100`, or in the config file as `max-items 100`. + +If you choose to use the config file, the default location is `$XDG_CONFIG_HOME/cliphist/config`. The format is a text file with one option per line, where each line is `<key> <value>`. For example: + +``` +# example cliphist config +max-items 1000 +max-dedupe-search 200 +``` + +The list of available options is: + +| CLI argument | Environment variable | Config file key | Description | +| ------------------ | --------------------------- | ----------------- | --------------------------------------------------------------------------------------------- | +| -max-dedupe-search | CLIPHIST_MAX_DEDEUPE_SEARCH | max-dedupe-search | (Optional) maximum number of last items to look through when finding duplicates (default 100) | +| -max-items | CLIPHIST_MAX_ITEMS | max-items | (Optional) maximum number of items to store (default 750) | +| -min-store-length | CLIPHIST_MIN_STORE_LENGTH | min-store-length | (Optional) minimum number of characters to store | +| -preview-width | CLIPHIST_PREVIEW_WIDTH | preview-width | (Optional) maximum number of characters to preview (default 100) | +| -db-path | CLIPHIST_DB_PATH | db-path | (Optional) path to db (default `$XDG_CACHE_HOME/cliphist/db`) | +| -config-path | CLIPHIST_CONFIG_PATH | | (Optional) path to config (default `$XDG_CONFIG_HOME/cliphist/config`) | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/testdata/decode-by-argument.txtar new/cliphist-0.7.0/testdata/decode-by-argument.txtar --- old/cliphist-0.6.1/testdata/decode-by-argument.txtar 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/testdata/decode-by-argument.txtar 2025-10-11 15:22:56.000000000 +0200 @@ -10,7 +10,7 @@ exec cliphist decode 2 stdout '^b$' -exec cliphist decode 3 +! exec cliphist decode 3 stdout '^$' ! exec cliphist decode diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/testdata/min-store-length.txtar new/cliphist-0.7.0/testdata/min-store-length.txtar --- old/cliphist-0.6.1/testdata/min-store-length.txtar 1970-01-01 01:00:00.000000000 +0100 +++ new/cliphist-0.7.0/testdata/min-store-length.txtar 2025-10-11 15:22:56.000000000 +0200 @@ -0,0 +1,35 @@ +exec randstr 16 +stdin stdout +exec cliphist store + +exec randstr 3 +stdin stdout +exec cliphist -min-store-length 3 store + +# we stored everything so far +exec cliphist list +stdout -count=2 '^.' + +exec randstr 4 +stdin stdout +exec cliphist -min-store-length 3 store + +# we can store the last, since 4 > 3 +exec cliphist list +stdout -count=3 '^.' + +exec randstr 2 +stdin stdout +exec cliphist -min-store-length 3 store + +# not the last, since 4 > 3 +exec cliphist list +stdout -count=3 '^.' + +exec randstr 3 +stdin stdout +exec cliphist -min-store-length 3 store + +# last is fine, 3 == 3 +exec cliphist list +stdout -count=4 '^.' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/testdata/test-image-and-preview-tiff.txtar new/cliphist-0.7.0/testdata/test-image-and-preview-tiff.txtar --- old/cliphist-0.6.1/testdata/test-image-and-preview-tiff.txtar 1970-01-01 01:00:00.000000000 +0100 +++ new/cliphist-0.7.0/testdata/test-image-and-preview-tiff.txtar 2025-10-11 15:22:56.000000000 +0200 @@ -0,0 +1,19 @@ +exec tiff +cp stdout in.tiff + +stdin stdout +exec cliphist store + +# check we render preview +exec cliphist list +stdout '\[\[ binary data \d+ KiB tiff 20x20 \]\]' + +stdin query +exec cliphist decode +cp stdout out.tiff + +# check we didn't lose any bytes +cmp in.tiff out.tiff + +-- query -- +1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cliphist-0.6.1/version.txt new/cliphist-0.7.0/version.txt --- old/cliphist-0.6.1/version.txt 2024-10-16 01:44:01.000000000 +0200 +++ new/cliphist-0.7.0/version.txt 2025-10-11 15:22:56.000000000 +0200 @@ -1 +1 @@ -0.6.1 +0.7.0 ++++++ vendor.tar.zst ++++++ ++++ 20158 lines of diff (skipped)
