Text In Clipboard History At Hand For Search Or dit

How to have text in clipboard history at hand for complex searches (regex, wildcards, ..) and editing:

  1. run a script to automatically and regurlarly export recent history into text file(s) (pro tip: autostart)
  2. open them in some text editor if script does not already (I use Kate for the search/replace and auto-reload capabilities)
  3. optional: find, search/replace, manually edit
  4. copy-paste to your work
  5. optional: keep open with auto-reload (edits are lost!).

because editing (3.) is overwritten on next history export, better edit in a separate document or use second a window/pane that does not auto-reload.

Here’s the script:

#!/usr/bin/env bash
# encoding: UTF-8

# exports clipboard history into text files
# one each for last minute and last 5 hours
# set location and frequency below

# #####################################################################################
# ####    SECURITY RISK IF LOCATION IS NOT PROTECTED!!! (E.G. COPIED PASSWORDS)    ####
# #####################################################################################

# possible improvements: >2 time ranges/files, file name auto-follows interval size, setting for auto-deletion on logout/login, ...

# --- User variables ---
SHORT_LOOKBACK=60     # seconds
LONG_LOOKBACK=18000   # seconds
UPDATE_FREQUENCY=15    # seconds
EXPORT_DIR="$HOME/.clipboard_history"
CURRENT_FILENAME="Clipboard last minute"
HISTORY_FILENAME="Clipboard last 5 hrs"
VISUAL_MARKER="――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
            # "⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓⁓"


set -euo pipefail

export LANG="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"

# --- Ensure export directory exists ---
if [[ ! -d "$EXPORT_DIR" ]]; then
  mkdir -p "$EXPORT_DIR"
fi

# --- Klipper data dir holding clipboard entry files ---
KLIPPER_DATA_DIR="$HOME/.local/share/klipper/data"

if [[ ! -d "$KLIPPER_DATA_DIR" ]]; then
  echo "Error: Klipper data directory does not exist: $KLIPPER_DATA_DIR" >&2
  exit 1
fi

kate "$EXPORT_DIR/$CURRENT_FILENAME" "$EXPORT_DIR/$HISTORY_FILENAME"

# --- Helper: concatenate files modified within last $seconds ---
concat_recent_files() {
  local max_age_seconds=$1
  local output_file=$2

  local time_limit
  time_limit=$(date -d "@$(( $(date +%s) - max_age_seconds ))" +%Y-%m-%dT%H:%M:%S)

  mapfile -t files < <(find "$KLIPPER_DATA_DIR" -type f -newermt "$time_limit" -printf '%T@ %p\n' | sort -nr | cut -d' ' -f2-)

  if (( ${#files[@]} == 0 )); then
    : > "$output_file"
    return
  fi

  {
    for f in "${files[@]}"; do
      cat "$f"
      echo
      echo "$(date '+%H:%M:%S, %d.%m.%Y') $VISUAL_MARKER"
      echo
    done
  } > "$output_file"
}

# --- Main loop ---
last_current_update=0
last_history_update=0

while true; do
  now=$(date +%s)

  if (( now - last_current_update >= SHORT_LOOKBACK )); then
    concat_recent_files $(( SHORT_LOOKBACK * 30 )) "$EXPORT_DIR/$CURRENT_FILENAME"
    last_current_update=$now
  fi

  if (( now - last_history_update >= LONG_LOOKBACK )); then
    concat_recent_files $(( LONG_LOOKBACK * 20 )) "$EXPORT_DIR/$HISTORY_FILENAME"
    last_history_update=$now
  fi

  sleep $UPDATE_FREQUENCY
done