Commit 6fe1a0ef6fde
Changed files (8)
dots
.config
niri
home
common
desktop
niri
sway
pkgs
tools
cliphist-cleanup
dots/.config/niri/config.kdl
@@ -186,6 +186,8 @@ binds {
Mod+Shift+D hotkey-overlay-title="Run Raffi" { spawn "raffi" "-I"; }
// FIXME do not use nix run, but needs niri configuration
Mod+Control+D hotkey-overlay-title="Emoji picker" { spawn "rofimoji" "--selector" "fuzzel" "--clipboarder" "wl-copy" "--typer" "wtype" "--action" "type" "copy"; }
+ Mod+Control+V hotkey-overlay-title="Clipboard History" { spawn "bash" "-c" "cliphist list | fuzzel --dmenu --width=100 --lines=20 | cliphist decode | wl-copy"; }
+ Mod+Control+Shift+V hotkey-overlay-title="Delete Clipboard Entry" { spawn "bash" "-c" "cliphist list | fuzzel --dmenu --width=100 --lines=20 | cliphist delete"; }
Super+Alt+L hotkey-overlay-title="Lock the Screen" { spawn "swaylock" "-m" "fill" "-i" "/home/vincent/desktop/pictures/lockscreen"; }
// You can also use a shell. Do this if you need pipes, multiple commands, etc.
home/common/desktop/niri/default.nix
@@ -31,6 +31,12 @@
cliphist = {
enable = true;
package = pkgs.cliphist;
+ extraOptions = [
+ "-max-dedupe-search"
+ "100"
+ "-max-items"
+ "1000"
+ ];
};
};
programs.niri = {
home/common/desktop/sway/default.nix
@@ -45,6 +45,12 @@ in
cliphist = {
enable = true;
package = pkgs.cliphist;
+ extraOptions = [
+ "-max-dedupe-search"
+ "100"
+ "-max-items"
+ "1000"
+ ];
};
};
pkgs/default.nix
@@ -26,6 +26,7 @@ in
gh-resolve-conflicts = pkgs.callPackage ../tools/gh-resolve-conflicts { };
arr = pkgs.callPackage ../tools/arr { };
download-kiwix-zim = pkgs.callPackage ../tools/download-kiwix-zim { };
+ cliphist-cleanup = pkgs.callPackage ../tools/cliphist-cleanup { };
toggle-color-scheme = pkgs.callPackage ./toggle-color-scheme { };
homepage = pkgs.callPackage ./homepage { inherit globals; };
tools/cliphist-cleanup/default.nix
@@ -0,0 +1,14 @@
+{ buildGoModule }:
+
+buildGoModule {
+ pname = "cliphist-cleanup";
+ version = "0.1.0";
+ src = ./.;
+
+ vendorHash = null;
+
+ meta = {
+ description = "Clean up cliphist clipboard history by pattern matching";
+ mainProgram = "cliphist-cleanup";
+ };
+}
tools/cliphist-cleanup/go.mod
@@ -0,0 +1,3 @@
+module cliphist-cleanup
+
+go 1.25.4
tools/cliphist-cleanup/main.go
@@ -0,0 +1,108 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "os/exec"
+ "regexp"
+ "strings"
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Fprintln(os.Stderr, "Usage: cliphist-cleanup <pattern> [pattern2] [pattern3] ...")
+ fmt.Fprintln(os.Stderr, "")
+ fmt.Fprintln(os.Stderr, "Examples:")
+ fmt.Fprintln(os.Stderr, " cliphist-cleanup 'Signed-off-by:'")
+ fmt.Fprintln(os.Stderr, " cliphist-cleanup '^# This is' 'Co-Authored-By:'")
+ fmt.Fprintln(os.Stderr, "")
+ fmt.Fprintln(os.Stderr, "Patterns are treated as regular expressions (case-insensitive).")
+ os.Exit(1)
+ }
+
+ // Compile patterns
+ patterns := make([]*regexp.Regexp, 0, len(os.Args)-1)
+ for _, pattern := range os.Args[1:] {
+ re, err := regexp.Compile("(?i)" + pattern)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error compiling pattern '%s': %v\n", pattern, err)
+ os.Exit(1)
+ }
+ patterns = append(patterns, re)
+ }
+
+ // Get clipboard history
+ cmd := exec.Command("cliphist", "list")
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error creating pipe: %v\n", err)
+ os.Exit(1)
+ }
+
+ if err := cmd.Start(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error starting cliphist list: %v\n", err)
+ os.Exit(1)
+ }
+
+ // Read entries and delete matching ones
+ scanner := bufio.NewScanner(stdout)
+ deleted := 0
+ checked := 0
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ checked++
+
+ // Check if line matches any pattern
+ matched := false
+ for _, re := range patterns {
+ if re.MatchString(line) {
+ matched = true
+ break
+ }
+ }
+
+ if matched {
+ // Delete this entry using delete-query
+ // The line format from cliphist list is: "ID\tCONTENT"
+ // We need to extract the content part after the tab
+ parts := strings.SplitN(line, "\t", 2)
+ if len(parts) < 2 {
+ continue
+ }
+
+ content := parts[1]
+ deleteCmd := exec.Command("cliphist", "delete-query", content)
+ if err := deleteCmd.Run(); err != nil {
+ fmt.Fprintf(os.Stderr, "Warning: Failed to delete entry: %v\n", err)
+ } else {
+ deleted++
+ fmt.Printf("Deleted: %s\n", truncate(content, 80))
+ }
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error reading cliphist output: %v\n", err)
+ os.Exit(1)
+ }
+
+ if err := cmd.Wait(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error waiting for cliphist: %v\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Printf("\nChecked %d entries, deleted %d entries\n", checked, deleted)
+}
+
+func truncate(s string, maxLen int) string {
+ // Replace newlines with spaces for display
+ s = strings.ReplaceAll(s, "\n", " ")
+ s = strings.ReplaceAll(s, "\r", " ")
+
+ if len(s) <= maxLen {
+ return s
+ }
+ return s[:maxLen-3] + "..."
+}
tools/cliphist-cleanup/README.md
@@ -0,0 +1,48 @@
+# cliphist-cleanup
+
+Clean up your clipboard history by deleting entries matching specific patterns.
+
+## Usage
+
+```bash
+cliphist-cleanup <pattern> [pattern2] [pattern3] ...
+```
+
+Patterns are treated as case-insensitive regular expressions.
+
+## Examples
+
+Delete all git sign-off entries:
+```bash
+cliphist-cleanup 'Signed-off-by:'
+```
+
+Delete multiple types of git commit messages:
+```bash
+cliphist-cleanup '# This is a combination' 'Co-Authored-By:'
+```
+
+Delete entries starting with specific text:
+```bash
+cliphist-cleanup '^password:' '^token:'
+```
+
+## How It Works
+
+1. Lists all clipboard history entries using `cliphist list`
+2. Matches each entry against the provided patterns
+3. Deletes matching entries using `cliphist delete-query`
+4. Reports the number of entries checked and deleted
+
+## Building
+
+```bash
+nix build .#cliphist-cleanup
+```
+
+## Installing
+
+Add to your home-manager packages or install directly:
+```bash
+nix profile install .#cliphist-cleanup
+```