DEV Community

Kir Axanov
Kir Axanov

Posted on

Shorts. Extra clipboard buffer with CopyQ

Hi!

Linux has two clipboard buffers: primary for mouse selection and clipboard for Ctrl+C / Ctrl+V.
But sometimes that's not enough and you want to keep some text around to paste later (like clipboard registers in Vim, but system-wide).
We can make this possible with CopyQ clipboard manager, which allows us to have multiple tabs for our copied data.

DISCLAIMER

  1. I’m talking about text only, other media types won’t work with the script below.
  2. In CopyQ settings check the (1) Store clipboard and (2) Store text selected using mouse.

In CopyQ settings check the  raw `(1) Store clipboard` endraw  and  raw `(2) Store text selected using mouse` endraw

Code

Here is a simple bash-script, that adds new tab and uses it as an extra clipboard buffer:

#!/usr/bin/env bash
# Allows to save text to extra buffer in CopyQ.
# Bind `copy()` to Alt+C, `paste()` to Alt+V.
# Alt+C copies selected text to extra buffer, current clipboard remains unchanged.
# Alt+V copies latest item in extra buffer to clipboard (you still have to paste it manually with Ctrl+V, `copyq paste` is laggy).
# If item in extra buffer is already in clipboard, then Alt+V removes it from clipboard (extra buffer still has it).

set -e

CMD="$1"  # One of: `copy`, `paste`
EXTRA_BUFFER="ExtraBuffer"

copy() {
  local selected=$(copyq selection)
  local old=$(copyq read -1)
  copyq tab "$EXTRA_BUFFER" add "$selected"
  copyq remove 0
  copyq copy "$old"
}

paste() {
  local clipboard=$(copyq read 0)
  local extra=$(copyq tab "$EXTRA_BUFFER" read 0)

  if [[ "$clipboard" == "$extra" ]]; then  # Restoring old copied item from clipboard.
    copyq remove 0
    local old=$(copyq read 0)
    copyq copy "$old"
  else  # Adding item from extra buffer to clipboard.
    local extra=$(copyq tab "$EXTRA_BUFFER" read 0)
    copyq write 0 "$extra"
    copyq copy "$extra"
  fi
}

case "$CMD" in
  copy) copy;;
  paste) paste;;
  *) ;;
esac
Enter fullscreen mode Exit fullscreen mode

You can bind it in i3wm like so (replace SCRIPT_PATH):

set $alt Mod1
bindsym $alt+C exec "bash SCRIPT_PATH copy"
bindsym $alt+V exec "bash SCRIPT_PATH paste"
Enter fullscreen mode Exit fullscreen mode

Bye!

Top comments (0)